Update to FreeBSD stable/12 2019-03-11

Git mirror commit 735fe7a0a5f9c265040e2e6654a01b081d6354f1.
This commit is contained in:
Sebastian Huber
2019-03-11 07:23:29 +01:00
parent d542c19668
commit eb1d30ad35
167 changed files with 5400 additions and 3657 deletions

View File

@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <net/pfvar.h>
#include <arpa/inet.h>
#include <search.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -86,7 +87,6 @@ void print_fromto(struct pf_rule_addr *, pf_osfp_t,
struct pf_rule_addr *, u_int8_t, u_int8_t, int, int);
int ifa_skip_if(const char *filter, struct node_host *p);
struct node_host *ifa_grouplookup(const char *, int);
struct node_host *host_if(const char *, int);
struct node_host *host_v4(const char *, int);
struct node_host *host_v6(const char *, int);
@@ -223,6 +223,19 @@ const struct pf_timeout pf_timeouts[] = {
{ NULL, 0 }
};
static struct hsearch_data isgroup_map;
static __attribute__((constructor)) void
pfctl_parser_init(void)
{
/*
* As hdestroy() will never be called on these tables, it will be
* safe to use references into the stored data as keys.
*/
if (hcreate_r(0, &isgroup_map) == 0)
err(1, "Failed to create interface group query response map");
}
const struct icmptypeent *
geticmptypebynumber(u_int8_t type, sa_family_t af)
{
@@ -1167,6 +1180,71 @@ check_netmask(struct node_host *h, sa_family_t af)
static struct node_host *iftab;
/*
* Retrieve the list of groups this interface is a member of and make sure
* each group is in the group map.
*/
static void
ifa_add_groups_to_map(char *ifa_name)
{
int s, len;
struct ifgroupreq ifgr;
struct ifg_req *ifg;
s = get_query_socket();
/* Get size of group list for this interface */
memset(&ifgr, 0, sizeof(ifgr));
strlcpy(ifgr.ifgr_name, ifa_name, IFNAMSIZ);
if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
err(1, "SIOCGIFGROUP");
/* Retrieve group list for this interface */
len = ifgr.ifgr_len;
ifgr.ifgr_groups =
(struct ifg_req *)calloc(len / sizeof(struct ifg_req),
sizeof(struct ifg_req));
if (ifgr.ifgr_groups == NULL)
err(1, "calloc");
if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
err(1, "SIOCGIFGROUP");
ifg = ifgr.ifgr_groups;
for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
len -= sizeof(struct ifg_req);
if (strcmp(ifg->ifgrq_group, "all")) {
ENTRY item;
ENTRY *ret_item;
int *answer;
item.key = ifg->ifgrq_group;
if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0) {
struct ifgroupreq ifgr2;
/* Don't know the answer yet */
if ((answer = malloc(sizeof(int))) == NULL)
err(1, "malloc");
bzero(&ifgr2, sizeof(ifgr2));
strlcpy(ifgr2.ifgr_name, ifg->ifgrq_group,
sizeof(ifgr2.ifgr_name));
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr2) == 0)
*answer = ifgr2.ifgr_len;
else
*answer = 0;
item.key = strdup(ifg->ifgrq_group);
item.data = answer;
if (hsearch_r(item, ENTER, &ret_item,
&isgroup_map) == 0)
err(1, "interface group query response"
" map insert");
}
}
}
free(ifgr.ifgr_groups);
}
void
ifa_load(void)
{
@@ -1234,6 +1312,8 @@ ifa_load(void)
sizeof(struct in6_addr));
n->ifindex = ((struct sockaddr_in6 *)
ifa->ifa_addr)->sin6_scope_id;
} else if (n->af == AF_LINK) {
ifa_add_groups_to_map(ifa->ifa_name);
}
if ((n->ifname = strdup(ifa->ifa_name)) == NULL)
err(1, "ifa_load: strdup");
@@ -1251,7 +1331,7 @@ ifa_load(void)
freeifaddrs(ifap);
}
int
static int
get_socket_domain(void)
{
int sdom;
@@ -1271,31 +1351,54 @@ get_socket_domain(void)
return (sdom);
}
int
get_query_socket(void)
{
static int s = -1;
if (s == -1) {
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
err(1, "socket");
}
return (s);
}
/*
* Returns the response len if the name is a group, otherwise returns 0.
*/
static int
is_a_group(char *name)
{
ENTRY item;
ENTRY *ret_item;
item.key = name;
if (hsearch_r(item, FIND, &ret_item, &isgroup_map) == 0)
return (0);
return (*(int *)ret_item->data);
}
struct node_host *
ifa_exists(const char *ifa_name)
ifa_exists(char *ifa_name)
{
struct node_host *n;
struct ifgroupreq ifgr;
int s;
if (iftab == NULL)
ifa_load();
/* check wether this is a group */
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
err(1, "socket");
bzero(&ifgr, sizeof(ifgr));
strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
/* check whether this is a group */
s = get_query_socket();
if (is_a_group(ifa_name)) {
/* fake a node_host */
if ((n = calloc(1, sizeof(*n))) == NULL)
err(1, "calloc");
if ((n->ifname = strdup(ifa_name)) == NULL)
err(1, "strdup");
close(s);
return (n);
}
close(s);
for (n = iftab; n; n = n->next) {
if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ))
@@ -1306,23 +1409,20 @@ ifa_exists(const char *ifa_name)
}
struct node_host *
ifa_grouplookup(const char *ifa_name, int flags)
ifa_grouplookup(char *ifa_name, int flags)
{
struct ifg_req *ifg;
struct ifgroupreq ifgr;
int s, len;
struct node_host *n, *h = NULL;
if ((s = socket(get_socket_domain(), SOCK_DGRAM, 0)) == -1)
err(1, "socket");
s = get_query_socket();
len = is_a_group(ifa_name);
if (len == 0)
return (NULL);
bzero(&ifgr, sizeof(ifgr));
strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
close(s);
return (NULL);
}
len = ifgr.ifgr_len;
ifgr.ifgr_len = len;
if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
err(1, "calloc");
if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
@@ -1341,13 +1441,12 @@ ifa_grouplookup(const char *ifa_name, int flags)
}
}
free(ifgr.ifgr_groups);
close(s);
return (h);
}
struct node_host *
ifa_lookup(const char *ifa_name, int flags)
ifa_lookup(char *ifa_name, int flags)
{
struct node_host *p = NULL, *h = NULL, *n = NULL;
int got4 = 0, got6 = 0;