Support limited wildcards in the input tags for --tag-if.

This commit is contained in:
Geoff Back
2021-08-29 13:27:27 +01:00
committed by Simon Kelley
parent a42ee397f3
commit 79337f99ae
3 changed files with 43 additions and 1 deletions

View File

@@ -163,6 +163,9 @@ version 2.85
Tweak TFTP code to check sender of all received packets, as Tweak TFTP code to check sender of all received packets, as
specified in RFC 1350 para 4. specified in RFC 1350 para 4.
Support some wildcard matching of input tags to --tag-if.
Thanks to Geoff Back for the idea and the patch.
version 2.84 version 2.84
Fix a problem, introduced in 2.83, which could see DNS replies Fix a problem, introduced in 2.83, which could see DNS replies

View File

@@ -1435,6 +1435,12 @@ Any number of set: and tag: forms may appear, in any order.
tag set by another tag set by another
.B --tag-if, .B --tag-if,
the line which sets the tag must precede the one which tests it. the line which sets the tag must precede the one which tests it.
As an extension, the tag:<tag> clauses support limited wildcard matching,
similar to the matching in the \fB--interface\fP directive. This allows, for
example, using \fB--tag-if=set:ppp,tag:ppp*\fP to set the tag 'ppp' for all requests
received on any matching interface (ppp0, ppp1, etc). This can be used in conjunction
with the tag:!<tag> format meaning that no tag matching the wildcard may be set.
.TP .TP
.B \-J, --dhcp-ignore=tag:<tag>[,tag:<tag>] .B \-J, --dhcp-ignore=tag:<tag>[,tag:<tag>]
When all the given tags appear in the tag set ignore the host and do When all the given tags appear in the tag set ignore the host and do

View File

@@ -79,13 +79,46 @@ ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz; return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;
} }
/* like match_netid() except that the check can have a trailing * for wildcard */
/* started as a direct copy of match_netid() */
int match_netid_wild(struct dhcp_netid *check, struct dhcp_netid *pool)
{
struct dhcp_netid *tmp1;
for (; check; check = check->next)
{
const int check_len = strlen(check->net);
const int is_wc = (check->net[check_len - 1] == '*');
/* '#' for not is for backwards compat. */
if (check->net[0] != '!' && check->net[0] != '#')
{
for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
if (is_wc ? (strncmp(check->net, tmp1->net, check_len-1) == 0) :
(strcmp(check->net, tmp1->net) == 0))
break;
if (!tmp1)
return 0;
}
else
for (tmp1 = pool; tmp1; tmp1 = tmp1->next)
if (is_wc ? (strncmp((check->net)+1, tmp1->net, check_len-2) == 0) :
(strcmp((check->net)+1, tmp1->net) == 0))
return 0;
}
return 1;
}
struct dhcp_netid *run_tag_if(struct dhcp_netid *tags) struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)
{ {
struct tag_if *exprs; struct tag_if *exprs;
struct dhcp_netid_list *list; struct dhcp_netid_list *list;
/* this now uses match_netid_wild() above so that tag_if can
* be used to set a 'group of interfaces' tag.
*/
for (exprs = daemon->tag_if; exprs; exprs = exprs->next) for (exprs = daemon->tag_if; exprs; exprs = exprs->next)
if (match_netid(exprs->tag, tags, 1)) if (match_netid_wild(exprs->tag, tags))
for (list = exprs->set; list; list = list->next) for (list = exprs->set; list; list = list->next)
{ {
list->list->next = tags; list->list->next = tags;