|
version 1.1, 2012/02/21 23:32:47
|
version 1.1.1.4, 2019/10/22 13:49:55
|
|
Line 19
|
Line 19
|
| #include "netgraph.h" |
#include "netgraph.h" |
| #include "util.h" |
#include "util.h" |
| |
|
| |
#include <sys/types.h> |
| #include <sys/sockio.h> |
#include <sys/sockio.h> |
| #include <sys/sysctl.h> |
#include <sys/sysctl.h> |
| |
#include <sys/param.h> |
| #include <net/if.h> |
#include <net/if.h> |
| #include <net/if_types.h> |
#include <net/if_types.h> |
| #include <net/if_dl.h> |
#include <net/if_dl.h> |
|
Line 59
|
Line 61
|
| #include <pcap.h> |
#include <pcap.h> |
| #endif |
#endif |
| |
|
| |
#include <string.h> |
| |
|
| /* |
/* |
| * DEFINITIONS |
* DEFINITIONS |
| */ |
*/ |
|
Line 94
|
Line 98
|
| static void IfaceNgIpv6Shutdown(Bund b); |
static void IfaceNgIpv6Shutdown(Bund b); |
| |
|
| #ifdef USE_NG_NETFLOW |
#ifdef USE_NG_NETFLOW |
| static int IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out); | static int IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out, int v6); |
| static int IfaceSetupNetflow(Bund b, char in, char out); | static int IfaceSetupNetflow(Bund b, char in, char out, int v6); |
| static void IfaceShutdownNetflow(Bund b, char in, char out); | static void IfaceShutdownNetflow(Bund b, char in, char out, int v6); |
| #endif |
#endif |
| |
|
| #ifdef USE_NG_IPACCT |
#ifdef USE_NG_IPACCT |
|
Line 136
|
Line 140
|
| #ifdef USE_IPFW |
#ifdef USE_IPFW |
| static int IfaceAllocACL (struct acl_pool ***ap, int start, char * ifname, int number); |
static int IfaceAllocACL (struct acl_pool ***ap, int start, char * ifname, int number); |
| static int IfaceFindACL (struct acl_pool *ap, char * ifname, int number); |
static int IfaceFindACL (struct acl_pool *ap, char * ifname, int number); |
| static char * IFaceParseACL (char * src, char * ifname); | static char * IfaceParseACL (char * src, IfaceState iface); |
| | static char * IfaceFixAclForDelete(char *r, char *buf, size_t len); |
| #endif |
#endif |
| |
|
| static int IfaceSetName(Bund b, const char * ifname); |
static int IfaceSetName(Bund b, const char * ifname); |
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| static int IfaceSetDescr(Bund b, const char * ifdescr); |
static int IfaceSetDescr(Bund b, const char * ifdescr); |
| |
static void IfaceFreeDescr(IfaceState iface); |
| #endif |
#endif |
| #ifdef SIOCAIFGROUP |
#ifdef SIOCAIFGROUP |
| static int IfaceAddGroup(Bund b, const char * ifgroup); |
static int IfaceAddGroup(Bund b, const char * ifgroup); |
|
Line 156
|
Line 162
|
| IfaceSetCommand, NULL, 2, (void *) SET_ADDRS }, |
IfaceSetCommand, NULL, 2, (void *) SET_ADDRS }, |
| { "route {dest}[/{width}]", "Add IP route", |
{ "route {dest}[/{width}]", "Add IP route", |
| IfaceSetCommand, NULL, 2, (void *) SET_ROUTE }, |
IfaceSetCommand, NULL, 2, (void *) SET_ROUTE }, |
| { "mtu {size}", "Set max allowed interface MTU", | { "mtu {size} [override]", "Set max allowed or override interface MTU", |
| IfaceSetCommand, NULL, 2, (void *) SET_MTU }, |
IfaceSetCommand, NULL, 2, (void *) SET_MTU }, |
| { "name [{name}]", "Set interface name", |
{ "name [{name}]", "Set interface name", |
| IfaceSetCommand, NULL, 2, (void *) SET_NAME }, |
IfaceSetCommand, NULL, 2, (void *) SET_NAME }, |
|
Line 192
|
Line 198
|
| static const struct confinfo gConfList[] = { |
static const struct confinfo gConfList[] = { |
| { 0, IFACE_CONF_ONDEMAND, "on-demand" }, |
{ 0, IFACE_CONF_ONDEMAND, "on-demand" }, |
| { 0, IFACE_CONF_PROXY, "proxy-arp" }, |
{ 0, IFACE_CONF_PROXY, "proxy-arp" }, |
| |
{ 0, IFACE_CONF_KEEP_TIMEOUT, "keep-timeout" }, |
| #ifdef USE_NG_TCPMSS |
#ifdef USE_NG_TCPMSS |
| { 0, IFACE_CONF_TCPMSSFIX, "tcpmssfix" }, |
{ 0, IFACE_CONF_TCPMSSFIX, "tcpmssfix" }, |
| #endif |
#endif |
|
Line 225
|
Line 232
|
| |
|
| #ifdef USE_NG_BPF |
#ifdef USE_NG_BPF |
| /* A BPF filter that matches TCP SYN packets */ |
/* A BPF filter that matches TCP SYN packets */ |
| static const struct bpf_insn gTCPSYNProg[] = { | static const struct bpf_insn gTCPSYNProg[] __attribute__((used)) = { |
| /*00*/ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9), /* A <- IP protocol */ |
/*00*/ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9), /* A <- IP protocol */ |
| /*01*/ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 6), /* !TCP => 8 */ |
/*01*/ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_TCP, 0, 6), /* !TCP => 8 */ |
| /*02*/ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 6), /* A <- fragmentation offset */ |
/*02*/ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 6), /* A <- fragmentation offset */ |
|
Line 258
|
Line 265
|
| 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}} |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}} |
| static const struct in6_addr in6mask128 = IN6MASK128; |
static const struct in6_addr in6mask128 = IN6MASK128; |
| |
|
| |
#ifdef SIOCSIFDESCR |
| |
void |
| |
IfaceFreeDescr(IfaceState iface) |
| |
{ |
| |
if (iface->ifdescr != NULL) |
| |
Freee(iface->ifdescr); |
| |
if (iface->conf.ifdescr != NULL) |
| |
Freee(iface->conf.ifdescr); |
| |
iface->ifdescr = iface->conf.ifdescr = NULL; |
| |
} |
| |
#endif |
| |
|
| /* |
/* |
| * IfaceInit() |
* IfaceInit() |
|
Line 271 IfaceInit(Bund b)
|
Line 289 IfaceInit(Bund b)
|
| /* Default configuration */ |
/* Default configuration */ |
| iface->mtu = NG_IFACE_MTU_DEFAULT; |
iface->mtu = NG_IFACE_MTU_DEFAULT; |
| iface->max_mtu = NG_IFACE_MTU_DEFAULT; |
iface->max_mtu = NG_IFACE_MTU_DEFAULT; |
| |
iface->mtu_override = 0; |
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| iface->ifdescr = NULL; |
iface->ifdescr = NULL; |
| iface->conf.ifdescr = NULL; |
iface->conf.ifdescr = NULL; |
| #endif |
#endif |
| Disable(&iface->options, IFACE_CONF_ONDEMAND); |
Disable(&iface->options, IFACE_CONF_ONDEMAND); |
| Disable(&iface->options, IFACE_CONF_PROXY); |
Disable(&iface->options, IFACE_CONF_PROXY); |
| |
Disable(&iface->options, IFACE_CONF_KEEP_TIMEOUT); |
| Disable(&iface->options, IFACE_CONF_TCPMSSFIX); |
Disable(&iface->options, IFACE_CONF_TCPMSSFIX); |
| #ifdef USE_NG_NAT |
#ifdef USE_NG_NAT |
| NatInit(b); |
NatInit(b); |
|
Line 298 IfaceInst(Bund b, Bund bt)
|
Line 318 IfaceInst(Bund b, Bund bt)
|
| |
|
| memcpy(iface, &bt->iface, sizeof(*iface)); |
memcpy(iface, &bt->iface, sizeof(*iface)); |
| |
|
| |
#ifdef SIOCSIFDESCR |
| |
/* Copy interface description from template config to current */ |
| |
if (bt->iface.conf.ifdescr) |
| |
iface->conf.ifdescr = Mstrdup(MB_IFACE, bt->iface.conf.ifdescr); |
| |
if (bt->iface.ifdescr) |
| |
iface->ifdescr = Mstrdup(MB_IFACE, bt->iface.ifdescr); |
| |
#endif |
| /* Copy interface name from template config to current */ |
/* Copy interface name from template config to current */ |
| if (bt->iface.conf.ifname[0] != 0 && b->tmpl == 0) { |
if (bt->iface.conf.ifname[0] != 0 && b->tmpl == 0) { |
| snprintf(iface->conf.ifname, sizeof(iface->conf.ifname), "%s%d", |
snprintf(iface->conf.ifname, sizeof(iface->conf.ifname), "%s%d", |
|
Line 316 IfaceDestroy(Bund b)
|
Line 343 IfaceDestroy(Bund b)
|
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| IfaceState const iface = &b->iface; |
IfaceState const iface = &b->iface; |
| |
|
| if (iface->conf.ifdescr != NULL) | IfaceFreeDescr(iface); |
| Freee(iface->conf.ifdescr); | |
| #endif |
#endif |
| } |
} |
| |
|
|
Line 431 IfaceUp(Bund b, int ready)
|
Line 457 IfaceUp(Bund b, int ready)
|
| |
|
| /* Start Session timer */ |
/* Start Session timer */ |
| if (b->params.session_timeout > 0) { |
if (b->params.session_timeout > 0) { |
| session_timeout = b->params.session_timeout; | if (Enabled(&iface->options, IFACE_CONF_KEEP_TIMEOUT)) { |
| | session_timeout = b->params.session_timeout - \ |
| | (iface->last_up - b->last_up); |
| | Log(LG_IFACE2, ("[%s] IFACE: keep session-timeout at: %d seconds", |
| | b->name, session_timeout)); |
| | } else { |
| | session_timeout = b->params.session_timeout; |
| | } |
| } else if (iface->session_timeout > 0) { |
} else if (iface->session_timeout > 0) { |
| session_timeout = iface->session_timeout; |
session_timeout = iface->session_timeout; |
| } |
} |
|
Line 442 IfaceUp(Bund b, int ready)
|
Line 475 IfaceUp(Bund b, int ready)
|
| if (session_timeout > INT_MAX / 1100) { |
if (session_timeout > INT_MAX / 1100) { |
| session_timeout = INT_MAX / 1100; |
session_timeout = INT_MAX / 1100; |
| Log(LG_ERR, ("[%s] IFACE: session-timeout limited to %d seconds", |
Log(LG_ERR, ("[%s] IFACE: session-timeout limited to %d seconds", |
| b->name, session_timeout)); | b->name, session_timeout)); |
| } |
} |
| TimerInit(&iface->sessionTimer, "IfaceSession", |
TimerInit(&iface->sessionTimer, "IfaceSession", |
| session_timeout * SECONDS, IfaceSessionTimeout, b); |
session_timeout * SECONDS, IfaceSessionTimeout, b); |
|
Line 488 IfaceUp(Bund b, int ready)
|
Line 521 IfaceUp(Bund b, int ready)
|
| if (b->params.ifdescr != NULL) { |
if (b->params.ifdescr != NULL) { |
| if (IfaceSetDescr(b, b->params.ifdescr) != -1) { |
if (IfaceSetDescr(b, b->params.ifdescr) != -1) { |
| Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Add description \"%s\"", |
Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Add description \"%s\"", |
| b->name, b->params.ifdescr)); | b->name, iface->ifdescr)); |
| iface->ifdescr = b->params.ifdescr; | |
| } |
} |
| |
} else if (iface->conf.ifdescr != NULL) { |
| |
if (IfaceSetDescr(b, iface->conf.ifdescr) != -1) { |
| |
Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Add description \"%s\"", |
| |
b->name, iface->ifdescr)); |
| |
} |
| } |
} |
| #endif |
#endif |
| #ifdef SIOCAIFGROUP |
#ifdef SIOCAIFGROUP |
|
Line 558 IfaceUp(Bund b, int ready)
|
Line 595 IfaceUp(Bund b, int ready)
|
| } |
} |
| acls = b->params.acl_queue; |
acls = b->params.acl_queue; |
| while (acls != NULL) { |
while (acls != NULL) { |
| buf = IFaceParseACL(acls->rule,iface->ifname); | buf = IfaceParseACL(acls->rule, iface); |
| ExecCmd(LG_IFACE2, b->name, "%s queue %d config %s", PATH_IPFW, acls->real_number, buf); |
ExecCmd(LG_IFACE2, b->name, "%s queue %d config %s", PATH_IPFW, acls->real_number, buf); |
| Freee(buf); |
Freee(buf); |
| acls = acls->next; |
acls = acls->next; |
| } |
} |
| acls = b->params.acl_table; |
acls = b->params.acl_table; |
| while (acls != NULL) { |
while (acls != NULL) { |
| acl = Mdup(MB_IFACE, acls, sizeof(struct acl) + strlen(acls->rule)); | /* allow both %aX and `peer_addr` macros */ |
| | buf = IfaceParseACL(acls->rule, iface); |
| | acl = Mdup2(MB_IPFW, acls, sizeof(struct acl), sizeof(struct acl) + strlen(buf)); |
| | strcpy(acl->rule, buf); |
| | Freee(buf); |
| acl->next = iface->tables; |
acl->next = iface->tables; |
| iface->tables = acl; |
iface->tables = acl; |
| ExecCmd(LG_IFACE2, b->name, "%s table %d add %s", PATH_IPFW, acls->real_number, acls->rule); | if (strncmp(acl->rule, "peer_addr", 9) == 0) { |
| | char hisaddr[20]; |
| | ExecCmd(LG_IFACE2, b->name, "%s table %d add %s", |
| | PATH_IPFW, acl->real_number, |
| | u_addrtoa(&iface->peer_addr, hisaddr, sizeof(hisaddr))); |
| | } else { |
| | ExecCmd(LG_IFACE2, b->name, "%s table %d add %s", PATH_IPFW, acl->real_number, acl->rule); |
| | } |
| acls = acls->next; |
acls = acls->next; |
| }; |
}; |
| acls = b->params.acl_rule; |
acls = b->params.acl_rule; |
| while (acls != NULL) { |
while (acls != NULL) { |
| buf = IFaceParseACL(acls->rule, iface->ifname); | buf = IfaceParseACL(acls->rule, iface); |
| ExecCmd(LG_IFACE2, b->name, "%s add %d %s via %s", PATH_IPFW, acls->real_number, buf, iface->ifname); |
ExecCmd(LG_IFACE2, b->name, "%s add %d %s via %s", PATH_IPFW, acls->real_number, buf, iface->ifname); |
| Freee(buf); |
Freee(buf); |
| acls = acls->next; |
acls = acls->next; |
|
Line 645 IfaceDown(Bund b)
|
Line 693 IfaceDown(Bund b)
|
| }; |
}; |
| acl = iface->tables; |
acl = iface->tables; |
| while (acl != NULL) { |
while (acl != NULL) { |
| ExecCmd(LG_IFACE2, b->name, "%s table %d delete %s", | if (strncmp(acl->rule, "peer_addr", 9) == 0) { |
| PATH_IPFW, acl->real_number, acl->rule); | char hisaddr[20]; |
| | ExecCmd(LG_IFACE2, b->name, "%s table %d delete %s", |
| | PATH_IPFW, acl->real_number, |
| | u_addrtoa(&iface->peer_addr, hisaddr, sizeof(hisaddr))); |
| | } else { |
| | char buf[ACL_LEN]; |
| | ExecCmd(LG_IFACE2, b->name, "%s table %d delete %s", |
| | PATH_IPFW, acl->real_number, |
| | IfaceFixAclForDelete(acl->rule, buf, sizeof(buf))); |
| | } |
| aclnext = acl->next; |
aclnext = acl->next; |
| Freee(acl); |
Freee(acl); |
| acl = aclnext; |
acl = aclnext; |
|
Line 688 IfaceDown(Bund b)
|
Line 745 IfaceDown(Bund b)
|
| PATH_IPFW, cb); |
PATH_IPFW, cb); |
| #endif /* USE_IPFW */ |
#endif /* USE_IPFW */ |
| |
|
| |
/* Clearing self and peer addresses */ |
| |
u_rangeclear(&iface->self_addr); |
| |
u_addrclear(&iface->peer_addr); |
| |
u_addrclear(&iface->self_ipv6_addr); |
| |
u_addrclear(&iface->peer_ipv6_addr); |
| |
|
| /* Revert interface name and description */ |
/* Revert interface name and description */ |
| |
|
| if (strcmp(iface->ngname, iface->ifname) != 0) { |
if (strcmp(iface->ngname, iface->ifname) != 0) { |
|
Line 704 IfaceDown(Bund b)
|
Line 767 IfaceDown(Bund b)
|
| } |
} |
| } |
} |
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| if (iface->ifdescr != NULL) { | if ((iface->ifdescr != NULL) |
| | && (IfaceSetDescr(b, iface->conf.ifdescr) != -1)) { |
| if (iface->conf.ifdescr != NULL) { |
if (iface->conf.ifdescr != NULL) { |
| /* Restore to config defined */ |
|
| if (IfaceSetDescr(b, iface->conf.ifdescr) != -1) { |
|
| Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Set description \"%s\"", |
Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Set description \"%s\"", |
| b->name, iface->conf.ifdescr)); | b->name, iface->ifdescr)); |
| iface->ifdescr = iface->conf.ifdescr; | |
| } else | |
| iface->ifdescr = NULL; | |
| } else { |
} else { |
| /* Restore to original (empty) */ |
|
| if (IfaceSetDescr(b, "") != -1) { |
|
| Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Clear description", |
Log(LG_BUND|LG_IFACE, ("[%s] IFACE: Clear description", |
| b->name)); |
b->name)); |
| } |
|
| iface->ifdescr = NULL; |
|
| } |
} |
| } |
} |
| #endif |
#endif |
|
Line 770 IfaceAllocACL(struct acl_pool ***ap, int start, char *
|
Line 825 IfaceAllocACL(struct acl_pool ***ap, int start, char *
|
| int i; |
int i; |
| struct acl_pool **rp,*rp1; |
struct acl_pool **rp,*rp1; |
| |
|
| rp1 = Malloc(MB_IFACE, sizeof(struct acl_pool)); | rp1 = Malloc(MB_IPFW, sizeof(struct acl_pool)); |
| strlcpy(rp1->ifname, ifname, sizeof(rp1->ifname)); |
strlcpy(rp1->ifname, ifname, sizeof(rp1->ifname)); |
| rp1->acl_number = number; |
rp1->acl_number = number; |
| |
|
|
Line 816 IfaceFindACL (struct acl_pool *ap, char * ifname, int
|
Line 871 IfaceFindACL (struct acl_pool *ap, char * ifname, int
|
| } |
} |
| |
|
| /* |
/* |
| * IFaceParseACL () | * IfaceParseACL () |
| * |
* |
| * Parces ACL and replaces %r, %p and %q macroses | * Parses ACL and replaces %r, %p and %q macroses |
| * by the real numbers of rules, queues and pipes. |
* by the real numbers of rules, queues and pipes. |
| |
* |
| |
* Also replaces %a1 and a2 with the remote(peer) |
| |
* or local(self) IP address respectively. |
| */ |
*/ |
| |
|
| static char * |
static char * |
| IFaceParseACL (char * src, char * ifname) | IfaceParseACL (char * src, IfaceState iface) |
| { |
{ |
| char *buf,*buf1; |
char *buf,*buf1; |
| char *begin,*param,*end; |
char *begin,*param,*end; |
| char t; |
char t; |
| int num,real_number; |
int num,real_number; |
| struct acl_pool *ap; |
struct acl_pool *ap; |
| |
char hisaddr[20]; |
| |
int ipmode = 0; /* 0 - normal macro, 1 - IP address macro */ |
| |
|
| buf = Malloc(MB_IFACE, ACL_LEN); | buf = Malloc(MB_IPFW, ACL_LEN); |
| buf1 = Malloc(MB_IFACE, ACL_LEN); | buf1 = Malloc(MB_IPFW, ACL_LEN); |
| |
|
| strlcpy(buf, src, ACL_LEN); |
strlcpy(buf, src, ACL_LEN); |
| do { |
do { |
|
Line 854 IFaceParseACL (char * src, char * ifname)
|
Line 914 IFaceParseACL (char * src, char * ifname)
|
| case 't': |
case 't': |
| ap = table_pool; |
ap = table_pool; |
| break; |
break; |
| |
case 'a': |
| |
ipmode = 1; |
| |
if (num == 1) |
| |
u_addrtoa(&iface->peer_addr, hisaddr, sizeof(hisaddr)); |
| |
else if (num == 2) |
| |
u_rangetoa(&iface->self_addr, hisaddr, sizeof(hisaddr)); |
| |
else |
| |
ipmode = 0; |
| |
ap = NULL; |
| |
break; |
| default: |
default: |
| ap = NULL; |
ap = NULL; |
| }; |
}; |
| real_number = IfaceFindACL(ap,ifname,num); | if (ipmode) |
| if (end != NULL) { | { |
| snprintf(buf1, ACL_LEN, "%s%d %s", begin, real_number, end); | if (end != NULL) |
| } else { | snprintf(buf1, ACL_LEN, "%s%s %s", begin, hisaddr, end); |
| snprintf(buf1, ACL_LEN, "%s%d", begin, real_number); | else |
| }; | snprintf(buf1, ACL_LEN, "%s%s", begin, hisaddr); |
| | ipmode = 0; |
| | } |
| | else |
| | { |
| | real_number = IfaceFindACL(ap, iface->ifname, num); |
| | if (end != NULL) |
| | snprintf(buf1, ACL_LEN, "%s%d %s", begin, real_number, end); |
| | else |
| | snprintf(buf1, ACL_LEN, "%s%d", begin, real_number); |
| | } |
| strlcpy(buf, buf1, ACL_LEN); |
strlcpy(buf, buf1, ACL_LEN); |
| }; |
}; |
| }; |
}; |
|
Line 870 IFaceParseACL (char * src, char * ifname)
|
Line 950 IFaceParseACL (char * src, char * ifname)
|
| Freee(buf1); |
Freee(buf1); |
| return(buf); |
return(buf); |
| } |
} |
| |
|
| |
/* |
| |
* IfaceFixAclForDelete() |
| |
* |
| |
* Removes values from ipfw 'table-key value [...]' expression r, if any. |
| |
* Returns buf pointer for modified expression or original r pointer |
| |
* if no modifications were performed when no values were found or |
| |
* buf found too short. |
| |
* |
| |
* len is size of buf. Strings are zero-terminated. |
| |
* r and buf must point to non-overlapping memory areas. |
| |
*/ |
| |
|
| |
static char* |
| |
IfaceFixAclForDelete(char *r, char *buf, size_t len) |
| |
{ |
| |
static const char sep[] = " \t"; |
| |
char *limit, *s; |
| |
int i, state = 0; |
| |
|
| |
/* |
| |
* Possible state values: |
| |
* |
| |
* -1: skip value (otherwise copy); |
| |
* 0: first iteration, do copy; |
| |
* 1: not first iteration, do copy. |
| |
*/ |
| |
|
| |
s = buf; |
| |
limit = buf + len; |
| |
|
| |
for (r += strspn(r, sep); /* Skip leading spaces. */ |
| |
*r; /* Check for end of string. */ |
| |
r += i, r += strspn(r, sep)) /* Advance and skip spaces again. */ |
| |
{ |
| |
i = strcspn(r, sep); /* Find separator or end of string. */ |
| |
if (state == 0 && r[i] == '\0') /* No separators in the rule? */ |
| |
return r; |
| |
if (state < 0) { /* Skip value. */ |
| |
state = 1; |
| |
continue; |
| |
} |
| |
if (limit - s < i + 1 + state) /* Check space. */ |
| |
return r; |
| |
if (state != 0) /* Insert separator. */ |
| |
*s++ = ' '; |
| |
memcpy(s, r, i); /* Copy IP address from the rule. */ |
| |
s += i; |
| |
state = -1; |
| |
} |
| |
*s = '\0'; |
| |
|
| |
return buf; |
| |
} |
| #endif /* USE_IPFW */ |
#endif /* USE_IPFW */ |
| |
|
| /* |
/* |
|
Line 916 IfaceIpIfaceUp(Bund b, int ready)
|
Line 1050 IfaceIpIfaceUp(Bund b, int ready)
|
| /* Proxy ARP for peer if desired and peer's address is known */ |
/* Proxy ARP for peer if desired and peer's address is known */ |
| u_addrclear(&iface->proxy_addr); |
u_addrclear(&iface->proxy_addr); |
| if (Enabled(&iface->options, IFACE_CONF_PROXY)) { |
if (Enabled(&iface->options, IFACE_CONF_PROXY)) { |
| |
u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr)); |
| if (u_addrempty(&iface->peer_addr)) { |
if (u_addrempty(&iface->peer_addr)) { |
| Log(LG_IFACE, | Log(LG_IFACE, ("[%s] IFACE: Can't proxy arp for %s", |
| ("[%s] IFACE: Can't proxy arp for %s", | b->name, hisaddr)); |
| b->name, u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr)))); | |
| } else if (GetEther(&iface->peer_addr, &hwa) < 0) { |
} else if (GetEther(&iface->peer_addr, &hwa) < 0) { |
| Log(LG_IFACE, | Log(LG_IFACE, ("[%s] IFACE: No interface to proxy arp on for %s", |
| ("[%s] IFACE: No interface to proxy arp on for %s", | b->name, hisaddr)); |
| b->name, u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr)))); | |
| } else { |
} else { |
| ether = (u_char *) LLADDR(&hwa); |
ether = (u_char *) LLADDR(&hwa); |
| if (ExecCmdNosh(LG_IFACE2, b->name, |
if (ExecCmdNosh(LG_IFACE2, b->name, |
| "%s -S %s %x:%x:%x:%x:%x:%x pub", |
"%s -S %s %x:%x:%x:%x:%x:%x pub", |
| PATH_ARP, u_addrtoa(&iface->peer_addr,hisaddr,sizeof(hisaddr)), | PATH_ARP, hisaddr, |
| ether[0], ether[1], ether[2], |
ether[0], ether[1], ether[2], |
| ether[3], ether[4], ether[5]) == 0) |
ether[3], ether[4], ether[5]) == 0) |
| iface->proxy_addr = iface->peer_addr; | iface->proxy_addr = iface->peer_addr; |
| } |
} |
| } |
} |
| |
|
|
Line 969 IfaceIpIfaceUp(Bund b, int ready)
|
Line 1102 IfaceIpIfaceUp(Bund b, int ready)
|
| else |
else |
| ns2buf[0] = '\0'; |
ns2buf[0] = '\0'; |
| |
|
| res = ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s' '%s' '%s'", | res = ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s' '%s' '%s' '%s'", |
| iface->up_script, iface->ifname, u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)), | iface->up_script, iface->ifname, |
| | u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)), |
| u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), |
u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), |
| *b->params.authname ? b->params.authname : "-", |
*b->params.authname ? b->params.authname : "-", |
| ns1buf, ns2buf, *b->params.peeraddr ? b->params.peeraddr : "-"); | ns1buf, ns2buf, *b->params.peeraddr ? b->params.peeraddr : "-", |
| | b->params.filter_id ? b->params.filter_id : "-"); |
| if (res != 0) { |
if (res != 0) { |
| FsmFailure(&b->ipcp.fsm, FAIL_NEGOT_FAILURE); |
FsmFailure(&b->ipcp.fsm, FAIL_NEGOT_FAILURE); |
| return (-1); |
return (-1); |
|
Line 999 IfaceIpIfaceDown(Bund b)
|
Line 1134 IfaceIpIfaceDown(Bund b)
|
| if (*iface->down_script) { |
if (*iface->down_script) { |
| char selfbuf[40],peerbuf[40]; |
char selfbuf[40],peerbuf[40]; |
| |
|
| ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s'", | ExecCmd(LG_IFACE2, b->name, "%s %s inet %s %s '%s' '%s' '%s'", |
| iface->down_script, iface->ifname, u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)), | iface->down_script, iface->ifname, |
| | u_rangetoa(&iface->self_addr,selfbuf, sizeof(selfbuf)), |
| u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), |
u_addrtoa(&iface->peer_addr, peerbuf, sizeof(peerbuf)), |
| *b->params.authname ? b->params.authname : "-", |
*b->params.authname ? b->params.authname : "-", |
| *b->params.peeraddr ? b->params.peeraddr : "-"); | *b->params.peeraddr ? b->params.peeraddr : "-", |
| | b->params.filter_id ? b->params.filter_id : "-"); |
| } |
} |
| |
|
| /* Delete dynamic routes */ |
/* Delete dynamic routes */ |
|
Line 1056 IfaceIpv6IfaceUp(Bund b, int ready)
|
Line 1193 IfaceIpv6IfaceUp(Bund b, int ready)
|
| iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000; |
iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000; |
| iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000; |
iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000; |
| iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000; |
iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000; |
| iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4] = ((u_short*)b->ipv6cp.myintid)[0]; | bcopy(b->ipv6cp.myintid, &iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4], sizeof(b->ipv6cp.myintid)); |
| iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[5] = ((u_short*)b->ipv6cp.myintid)[1]; | bcopy(&iface->self_ipv6_addr.u.ip6, &b->ipv6cp.want_addr, sizeof(struct in6_addr)); |
| iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[6] = ((u_short*)b->ipv6cp.myintid)[2]; | |
| iface->self_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[7] = ((u_short*)b->ipv6cp.myintid)[3]; | |
| } else { |
} else { |
| u_addrcopy(&iface->conf.self_ipv6_addr, &iface->self_ipv6_addr); |
u_addrcopy(&iface->conf.self_ipv6_addr, &iface->self_ipv6_addr); |
| } |
} |
|
Line 1069 IfaceIpv6IfaceUp(Bund b, int ready)
|
Line 1204 IfaceIpv6IfaceUp(Bund b, int ready)
|
| iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000; |
iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[1] = 0x0000; |
| iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000; |
iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[2] = 0x0000; |
| iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000; |
iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[3] = 0x0000; |
| iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4] = ((u_short*)b->ipv6cp.hisintid)[0]; | bcopy(b->ipv6cp.hisintid, &iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[4], sizeof(b->ipv6cp.hisintid)); |
| iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[5] = ((u_short*)b->ipv6cp.hisintid)[1]; | bcopy(&iface->peer_ipv6_addr.u.ip6, &b->ipv6cp.peer_addr, sizeof(struct in6_addr)); |
| iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[6] = ((u_short*)b->ipv6cp.hisintid)[2]; | |
| iface->peer_ipv6_addr.u.ip6.__u6_addr.__u6_addr16[7] = ((u_short*)b->ipv6cp.hisintid)[3]; | |
| } else { |
} else { |
| u_addrcopy(&iface->conf.peer_ipv6_addr, &iface->peer_ipv6_addr); |
u_addrcopy(&iface->conf.peer_ipv6_addr, &iface->peer_ipv6_addr); |
| } |
} |
|
Line 1113 IfaceIpv6IfaceUp(Bund b, int ready)
|
Line 1246 IfaceIpv6IfaceUp(Bund b, int ready)
|
| char selfbuf[48],peerbuf[48]; |
char selfbuf[48],peerbuf[48]; |
| int res; |
int res; |
| |
|
| res = ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s'", | res = ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s' '%s'", |
| iface->up_script, iface->ifname, |
iface->up_script, iface->ifname, |
| u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname, |
u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname, |
| u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname, |
u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname, |
| *b->params.authname ? b->params.authname : "-", |
*b->params.authname ? b->params.authname : "-", |
| *b->params.peeraddr ? b->params.peeraddr : "-"); | *b->params.peeraddr ? b->params.peeraddr : "-", |
| | b->params.filter_id ? b->params.filter_id : "-"); |
| if (res != 0) { |
if (res != 0) { |
| FsmFailure(&b->ipv6cp.fsm, FAIL_NEGOT_FAILURE); |
FsmFailure(&b->ipv6cp.fsm, FAIL_NEGOT_FAILURE); |
| return (-1); |
return (-1); |
|
Line 1145 IfaceIpv6IfaceDown(Bund b)
|
Line 1279 IfaceIpv6IfaceDown(Bund b)
|
| if (*iface->down_script) { |
if (*iface->down_script) { |
| char selfbuf[48],peerbuf[48]; |
char selfbuf[48],peerbuf[48]; |
| |
|
| ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s'", | ExecCmd(LG_IFACE2, b->name, "%s %s inet6 %s%%%s %s%%%s '%s' '%s' '%s'", |
| iface->down_script, iface->ifname, |
iface->down_script, iface->ifname, |
| u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname, |
u_addrtoa(&iface->self_ipv6_addr, selfbuf, sizeof(selfbuf)), iface->ifname, |
| u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname, |
u_addrtoa(&iface->peer_ipv6_addr, peerbuf, sizeof(peerbuf)), iface->ifname, |
| *b->params.authname ? b->params.authname : "-", |
*b->params.authname ? b->params.authname : "-", |
| *b->params.peeraddr ? b->params.peeraddr : "-"); | *b->params.peeraddr ? b->params.peeraddr : "-", |
| | b->params.filter_id ? b->params.filter_id : "-"); |
| } |
} |
| |
|
| /* Delete dynamic routes */ |
/* Delete dynamic routes */ |
|
Line 1472 IfaceSetCommand(Context ctx, int ac, char *av[], void
|
Line 1607 IfaceSetCommand(Context ctx, int ac, char *av[], void
|
| case SET_MTU: |
case SET_MTU: |
| { |
{ |
| int max_mtu; |
int max_mtu; |
| |
int override; |
| |
|
| /* Check */ |
/* Check */ |
| if (ac != 1) | if (ac < 1 || ac > 2) |
| return(-1); |
return(-1); |
| |
|
| max_mtu = atoi(av[0]); |
max_mtu = atoi(av[0]); |
| |
override = 0; |
| |
|
| |
if (ac == 2 && av[1][0]) { |
| |
if (strcmp(av[1], "override") == 0) |
| |
override = 1; |
| |
else |
| |
Error("Invalid keyword %s", av[1]); |
| |
} |
| |
|
| if (max_mtu < IFACE_MIN_MTU || max_mtu > IFACE_MAX_MTU) |
if (max_mtu < IFACE_MIN_MTU || max_mtu > IFACE_MAX_MTU) |
| Error("Invalid interface mtu %d", max_mtu); | if (!override || max_mtu != 0) |
| iface->max_mtu = max_mtu; | Error("Invalid interface mtu %d", max_mtu); |
| | |
| | if (max_mtu != 0) |
| | iface->max_mtu = max_mtu; |
| | if (override) |
| | iface->mtu_override = max_mtu; |
| } |
} |
| break; |
break; |
| |
|
|
Line 1512 IfaceSetCommand(Context ctx, int ac, char *av[], void
|
Line 1662 IfaceSetCommand(Context ctx, int ac, char *av[], void
|
| break; |
break; |
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| case SET_DESCR: |
case SET_DESCR: |
| if (ctx->bund->tmpl) | IfaceFreeDescr(iface); |
| Error("Impossible to apply on template"); | |
| if (iface->conf.ifdescr != NULL) | |
| Freee(iface->conf.ifdescr); | |
| iface->conf.ifdescr = NULL; | |
| iface->ifdescr = NULL; | |
| switch (ac) { |
switch (ac) { |
| case 0: |
case 0: |
| return IfaceSetDescr(ctx->bund, ""); |
return IfaceSetDescr(ctx->bund, ""); |
| break; |
break; |
| case 1: |
case 1: |
| iface->conf.ifdescr = Mstrdup(MB_IFACE, av[0]); |
iface->conf.ifdescr = Mstrdup(MB_IFACE, av[0]); |
| if (IfaceSetDescr(ctx->bund, av[0]) == 0) { | return IfaceSetDescr(ctx->bund, av[0]); |
| iface->ifdescr = iface->conf.ifdescr; | |
| return(0); | |
| } else | |
| return(-1); | |
| break; |
break; |
| default: |
default: |
| return(-1); |
return(-1); |
|
Line 1612 IfaceStat(Context ctx, int ac, char *av[], void *arg)
|
Line 1753 IfaceStat(Context ctx, int ac, char *av[], void *arg)
|
| Printf("\tName : %s\r\n", iface->conf.ifname); |
Printf("\tName : %s\r\n", iface->conf.ifname); |
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| Printf("\tDescription : \"%s\"\r\n", |
Printf("\tDescription : \"%s\"\r\n", |
| (iface->conf.ifdescr != NULL) ? iface->conf.ifdescr : "<none>"); | (iface->ifdescr != NULL) ? iface->ifdescr : "<none>"); |
| #endif |
#endif |
| #ifdef SIOCAIFGROUP |
#ifdef SIOCAIFGROUP |
| Printf("\tGroup : %s\r\n", iface->conf.ifgroup); |
Printf("\tGroup : %s\r\n", iface->conf.ifgroup); |
| #endif |
#endif |
| Printf("\tMaximum MTU : %d bytes\r\n", iface->max_mtu); |
Printf("\tMaximum MTU : %d bytes\r\n", iface->max_mtu); |
| |
Printf("\tMTU override : %d bytes\r\n", iface->mtu_override); |
| Printf("\tIdle timeout : %d seconds\r\n", iface->idle_timeout); |
Printf("\tIdle timeout : %d seconds\r\n", iface->idle_timeout); |
| Printf("\tSession timeout : %d seconds\r\n", iface->session_timeout); |
Printf("\tSession timeout : %d seconds\r\n", iface->session_timeout); |
| if (!u_rangeempty(&iface->conf.self_addr)) { |
if (!u_rangeempty(&iface->conf.self_addr)) { |
|
Line 1748 IfaceSetMTU(Bund b, int mtu)
|
Line 1890 IfaceSetMTU(Bund b, int mtu)
|
| return; |
return; |
| } |
} |
| |
|
| if ((b->params.mtu > 0) && (mtu > b->params.mtu)) { | if (!iface->mtu_override && (b->params.mtu > 0) && (mtu > b->params.mtu)) { |
| mtu = b->params.mtu; |
mtu = b->params.mtu; |
| Log(LG_IFACE2, ("[%s] IFACE: forcing MTU of auth backend: %d bytes", |
Log(LG_IFACE2, ("[%s] IFACE: forcing MTU of auth backend: %d bytes", |
| b->name, mtu)); |
b->name, mtu)); |
| } |
} |
| |
|
| /* Limit MTU to configured maximum */ | /* Limit MTU to configured maximum/override */ |
| if (mtu > iface->max_mtu) | if (iface->mtu_override) { |
| | mtu = iface->mtu_override; |
| | Log(LG_IFACE2, ("[%s] IFACE: forcing MTU override: %d bytes", |
| | b->name, mtu)); |
| | } else if (mtu > iface->max_mtu) |
| mtu = iface->max_mtu; |
mtu = iface->max_mtu; |
| |
|
| /* Set MTU on interface */ |
/* Set MTU on interface */ |
|
Line 1785 IfaceChangeFlags(Bund b, int clear, int set)
|
Line 1931 IfaceChangeFlags(Bund b, int clear, int set)
|
| struct ifreq ifrq; |
struct ifreq ifrq; |
| int s, new_flags; |
int s, new_flags; |
| |
|
| Log(LG_IFACE2, ("[%s] IFACE: Change interface flags: -%d +%d", | Log(LG_IFACE2, ("[%s] IFACE: Change interface %s flags: -%d +%d", |
| b->name, clear, set)); | b->name, b->iface.ifname, clear, set)); |
| |
|
| if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { |
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { |
| Perror("[%s] IFACE: Can't get socket to change interface flags", b->name); |
Perror("[%s] IFACE: Can't get socket to change interface flags", b->name); |
|
Line 1795 IfaceChangeFlags(Bund b, int clear, int set)
|
Line 1941 IfaceChangeFlags(Bund b, int clear, int set)
|
| |
|
| memset(&ifrq, '\0', sizeof(ifrq)); |
memset(&ifrq, '\0', sizeof(ifrq)); |
| strlcpy(ifrq.ifr_name, b->iface.ifname, sizeof(ifrq.ifr_name)); |
strlcpy(ifrq.ifr_name, b->iface.ifname, sizeof(ifrq.ifr_name)); |
| ifrq.ifr_name[sizeof(ifrq.ifr_name) - 1] = '\0'; |
|
| if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) { |
if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) { |
| Perror("[%s] IFACE: ioctl(%s, %s)", b->name, b->iface.ifname, "SIOCGIFFLAGS"); | Perror("[%s] IFACE: ioctl(SIOCGIFFLAGS, %s)", b->name, b->iface.ifname); |
| close(s); |
close(s); |
| return; |
return; |
| } |
} |
|
Line 1810 IfaceChangeFlags(Bund b, int clear, int set)
|
Line 1955 IfaceChangeFlags(Bund b, int clear, int set)
|
| ifrq.ifr_flagshigh = new_flags >> 16; |
ifrq.ifr_flagshigh = new_flags >> 16; |
| |
|
| if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) { |
if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) { |
| Perror("[%s] IFACE: ioctl(%s, %s)", b->name, b->iface.ifname, "SIOCSIFFLAGS"); | Perror("[%s] IFACE: ioctl(SIOCSIFFLAGS, %s)", b->name, b->iface.ifname); |
| close(s); |
close(s); |
| return; |
return; |
| } |
} |
|
Line 1829 add_scope(struct sockaddr *sa, int ifindex)
|
Line 1974 add_scope(struct sockaddr *sa, int ifindex)
|
| if (!IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) && |
if (!IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) && |
| !IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr)) |
!IN6_IS_ADDR_MC_LINKLOCAL(&sa6->sin6_addr)) |
| return; |
return; |
| if (*(u_int16_t *)&sa6->sin6_addr.s6_addr[2] != 0) | if (sa6->sin6_addr.__u6_addr.__u6_addr16[1] != 0) |
| return; |
return; |
| *(u_int16_t *)&sa6->sin6_addr.s6_addr[2] = htons(ifindex); | sa6->sin6_addr.__u6_addr.__u6_addr16[1] = htons(ifindex); |
| } |
} |
| #endif |
#endif |
| |
|
|
Line 1902 IfaceChangeAddr(Bund b, int add, struct u_range *self,
|
Line 2047 IfaceChangeAddr(Bund b, int add, struct u_range *self,
|
| |
|
| res = ioctl(s, add?SIOCAIFADDR_IN6:SIOCDIFADDR_IN6, &ifra6); |
res = ioctl(s, add?SIOCAIFADDR_IN6:SIOCDIFADDR_IN6, &ifra6); |
| if (res == -1) { |
if (res == -1) { |
| Perror("[%s] IFACE: %s IPv6 address %s %s failed", | if (add && errno == EEXIST) { |
| b->name, add?"Adding":"Removing", add?"to":"from", b->iface.ifname); | /* this can happen if the kernel has already automatically added |
| | the same link-local address - ignore the error */ |
| | res = 0; |
| | } else { |
| | Perror("[%s] IFACE: %s IPv6 address %s %s failed", |
| | b->name, add?"Adding":"Removing", add?"to":"from", b->iface.ifname); |
| | } |
| } |
} |
| break; |
break; |
| |
|
|
Line 2070 IfaceNgIpInit(Bund b, int ready)
|
Line 2221 IfaceNgIpInit(Bund b, int ready)
|
| snprintf(hook, sizeof(hook), "4%d", b->id); |
snprintf(hook, sizeof(hook), "4%d", b->id); |
| |
|
| } else { |
} else { |
| |
|
| snprintf(path, sizeof(path), "[%x]:", b->nodeID); |
snprintf(path, sizeof(path), "[%x]:", b->nodeID); |
| strcpy(hook, NG_PPP_HOOK_INET); |
strcpy(hook, NG_PPP_HOOK_INET); |
| |
|
|
Line 2106 IfaceNgIpInit(Bund b, int ready)
|
Line 2256 IfaceNgIpInit(Bund b, int ready)
|
| Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) { |
Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) { |
| if (IfaceInitNetflow(b, path, hook, |
if (IfaceInitNetflow(b, path, hook, |
| Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)?1:0, |
Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)?1:0, |
| Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)?1:0)) | Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)?1:0, 0)) |
| goto fail; |
goto fail; |
| if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) |
| b->iface.nfin_up = 1; |
b->iface.nfin_up = 1; |
|
Line 2116 IfaceNgIpInit(Bund b, int ready)
|
Line 2266 IfaceNgIpInit(Bund b, int ready)
|
| #else /* NG_NETFLOW_CONF_INGRESS */ |
#else /* NG_NETFLOW_CONF_INGRESS */ |
| /* Connect a netflow node if configured */ |
/* Connect a netflow node if configured */ |
| if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) { |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) { |
| if (IfaceInitNetflow(b, path, hook, 1, 0)) | if (IfaceInitNetflow(b, path, hook, 1, 0, 0)) |
| goto fail; |
goto fail; |
| b->iface.nfin_up = 1; |
b->iface.nfin_up = 1; |
| } |
} |
| |
|
| if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) { |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) { |
| if (IfaceInitNetflow(b, path, hook, 0, 1)) | if (IfaceInitNetflow(b, path, hook, 0, 1, 0)) |
| goto fail; |
goto fail; |
| b->iface.nfout_up = 1; |
b->iface.nfout_up = 1; |
| } |
} |
|
Line 2160 IfaceNgIpInit(Bund b, int ready)
|
Line 2310 IfaceNgIpInit(Bund b, int ready)
|
| #ifdef USE_NG_NETFLOW |
#ifdef USE_NG_NETFLOW |
| #ifdef NG_NETFLOW_CONF_INGRESS |
#ifdef NG_NETFLOW_CONF_INGRESS |
| if (b->iface.nfin_up || b->iface.nfout_up) |
if (b->iface.nfin_up || b->iface.nfout_up) |
| IfaceSetupNetflow(b, b->iface.nfin_up, b->iface.nfout_up); | IfaceSetupNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 0); |
| #else /* NG_NETFLOW_CONF_INGRESS */ |
#else /* NG_NETFLOW_CONF_INGRESS */ |
| if (b->iface.nfin_up) |
if (b->iface.nfin_up) |
| IfaceSetupNetflow(b, 1, 0); | IfaceSetupNetflow(b, 1, 0, 0); |
| |
|
| if (b->iface.nfout_up) |
if (b->iface.nfout_up) |
| IfaceSetupNetflow(b, 0, 1); | IfaceSetupNetflow(b, 0, 1, 0); |
| #endif /* NG_NETFLOW_CONF_INGRESS */ |
#endif /* NG_NETFLOW_CONF_INGRESS */ |
| #endif /* USE_NG_NETFLOW */ |
#endif /* USE_NG_NETFLOW */ |
| } |
} |
|
Line 2210 IfaceNgIpShutdown(Bund b)
|
Line 2360 IfaceNgIpShutdown(Bund b)
|
| #ifdef USE_NG_NETFLOW |
#ifdef USE_NG_NETFLOW |
| #ifdef NG_NETFLOW_CONF_INGRESS |
#ifdef NG_NETFLOW_CONF_INGRESS |
| if (b->iface.nfin_up || b->iface.nfout_up) |
if (b->iface.nfin_up || b->iface.nfout_up) |
| IfaceShutdownNetflow(b, b->iface.nfin_up, b->iface.nfout_up); | IfaceShutdownNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 0); |
| b->iface.nfin_up = 0; |
b->iface.nfin_up = 0; |
| b->iface.nfout_up = 0; |
b->iface.nfout_up = 0; |
| #else /* NG_NETFLOW_CONF_INGRESS */ |
#else /* NG_NETFLOW_CONF_INGRESS */ |
| if (b->iface.nfin_up) |
if (b->iface.nfin_up) |
| IfaceShutdownNetflow(b, 1, 0); | IfaceShutdownNetflow(b, 1, 0, 0); |
| b->iface.nfin_up = 0; |
b->iface.nfin_up = 0; |
| if (b->iface.nfout_up) |
if (b->iface.nfout_up) |
| IfaceShutdownNetflow(b, 0, 1); | IfaceShutdownNetflow(b, 0, 1, 0); |
| b->iface.nfout_up = 0; |
b->iface.nfout_up = 0; |
| #endif /* NG_NETFLOW_CONF_INGRESS */ |
#endif /* NG_NETFLOW_CONF_INGRESS */ |
| #endif |
#endif |
|
Line 2263 IfaceNgIpv6Init(Bund b, int ready)
|
Line 2413 IfaceNgIpv6Init(Bund b, int ready)
|
| b->iface.tee6_up = 1; |
b->iface.tee6_up = 1; |
| } |
} |
| |
|
| |
#ifdef USE_NG_NETFLOW |
| |
#ifdef NG_NETFLOW_CONF_INGRESS |
| |
/* Connect a netflow node if configured */ |
| |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN) || |
| |
Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) { |
| |
if (IfaceInitNetflow(b, path, hook, |
| |
Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)?1:0, |
| |
Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)?1:0, 1)) |
| |
goto fail; |
| |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) |
| |
b->iface.nfin_up = 1; |
| |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) |
| |
b->iface.nfout_up = 1; |
| |
} |
| |
#else /* NG_NETFLOW_CONF_INGRESS */ |
| |
/* Connect a netflow node if configured */ |
| |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_IN)) { |
| |
if (IfaceInitNetflow(b, path, hook, 1, 0, 1)) |
| |
goto fail; |
| |
b->iface.nfin_up = 1; |
| |
} |
| |
|
| |
if (Enabled(&b->iface.options, IFACE_CONF_NETFLOW_OUT)) { |
| |
if (IfaceInitNetflow(b, path, hook, 0, 1, 1)) |
| |
goto fail; |
| |
b->iface.nfout_up = 1; |
| |
} |
| |
#endif /* NG_NETFLOW_CONF_INGRESS */ |
| |
#endif /* USE_NG_NETFLOW */ |
| } |
} |
| |
|
| |
#ifdef USE_NG_BPF |
| |
if (IfaceInitLimits(b, path, hook)) |
| |
goto fail; |
| |
#endif |
| |
|
| /* Connect graph to the iface node. */ |
/* Connect graph to the iface node. */ |
| strcpy(cn.ourhook, hook); |
strcpy(cn.ourhook, hook); |
| snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ngname); |
snprintf(cn.path, sizeof(cn.path), "%s:", b->iface.ngname); |
|
Line 2276 IfaceNgIpv6Init(Bund b, int ready)
|
Line 2460 IfaceNgIpv6Init(Bund b, int ready)
|
| goto fail; |
goto fail; |
| } |
} |
| |
|
| |
if (ready) { |
| |
#ifdef USE_NG_NETFLOW |
| |
#ifdef NG_NETFLOW_CONF_INGRESS |
| |
if (b->iface.nfin_up || b->iface.nfout_up) |
| |
IfaceSetupNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 1); |
| |
#else /* NG_NETFLOW_CONF_INGRESS */ |
| |
if (b->iface.nfin_up) |
| |
IfaceSetupNetflow(b, 1, 0, 1); |
| |
|
| |
if (b->iface.nfout_up) |
| |
IfaceSetupNetflow(b, 0, 1, 1); |
| |
#endif /* NG_NETFLOW_CONF_INGRESS */ |
| |
#endif /* USE_NG_NETFLOW */ |
| |
} |
| |
|
| |
#ifdef USE_NG_BPF |
| |
IfaceSetupLimits(b); |
| |
#endif |
| |
|
| /* OK */ |
/* OK */ |
| return(0); |
return(0); |
| |
|
|
Line 2292 IfaceNgIpv6Shutdown(Bund b)
|
Line 2495 IfaceNgIpv6Shutdown(Bund b)
|
| { |
{ |
| char path[NG_PATHSIZ]; |
char path[NG_PATHSIZ]; |
| |
|
| |
#ifdef USE_NG_BPF |
| |
IfaceShutdownLimits(b); /* Limits must shutdown first to save final stats. */ |
| |
#endif |
| if (b->iface.tee6_up) |
if (b->iface.tee6_up) |
| IfaceShutdownTee(b, 1); |
IfaceShutdownTee(b, 1); |
| b->iface.tee6_up = 0; |
b->iface.tee6_up = 0; |
| |
#ifdef USE_NG_NETFLOW |
| |
#ifdef NG_NETFLOW_CONF_INGRESS |
| |
if (b->iface.nfin_up || b->iface.nfout_up) |
| |
IfaceShutdownNetflow(b, b->iface.nfin_up, b->iface.nfout_up, 1); |
| |
b->iface.nfin_up = 0; |
| |
b->iface.nfout_up = 0; |
| |
#else /* NG_NETFLOW_CONF_INGRESS */ |
| |
if (b->iface.nfin_up) |
| |
IfaceShutdownNetflow(b, 1, 0, 1); |
| |
b->iface.nfin_up = 0; |
| |
if (b->iface.nfout_up) |
| |
IfaceShutdownNetflow(b, 0, 1, 1); |
| |
b->iface.nfout_up = 0; |
| |
#endif /* NG_NETFLOW_CONF_INGRESS */ |
| |
#endif |
| |
|
| snprintf(path, sizeof(path), "[%x]:", b->nodeID); |
snprintf(path, sizeof(path), "[%x]:", b->nodeID); |
| NgFuncDisconnect(gLinksCsock, b->name, path, NG_PPP_HOOK_IPV6); |
NgFuncDisconnect(gLinksCsock, b->name, path, NG_PPP_HOOK_IPV6); |
|
Line 2381 IfaceSetupNAT(Bund b)
|
Line 2602 IfaceSetupNAT(Bund b)
|
| { |
{ |
| NatState const nat = &b->iface.nat; |
NatState const nat = &b->iface.nat; |
| char path[NG_PATHSIZ]; |
char path[NG_PATHSIZ]; |
| |
#ifdef NG_NAT_DESC_LENGTH |
| int k; |
int k; |
| |
union { |
| |
u_char buf[sizeof(struct ng_mesg) + sizeof(uint32_t)]; |
| |
struct ng_mesg reply; |
| |
} u; |
| |
uint32_t *const nat_id = (uint32_t *)(void *)u.reply.data; |
| |
#endif |
| |
|
| |
snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name); |
| if (u_addrempty(&nat->alias_addr)) { |
if (u_addrempty(&nat->alias_addr)) { |
| snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name); |
|
| if (NgSendMsg(gLinksCsock, path, |
if (NgSendMsg(gLinksCsock, path, |
| NGM_NAT_COOKIE, NGM_NAT_SET_IPADDR, |
NGM_NAT_COOKIE, NGM_NAT_SET_IPADDR, |
| &b->iface.self_addr.addr.u.ip4, |
&b->iface.self_addr.addr.u.ip4, |
|
Line 2396 IfaceSetupNAT(Bund b)
|
Line 2624 IfaceSetupNAT(Bund b)
|
| #ifdef NG_NAT_DESC_LENGTH |
#ifdef NG_NAT_DESC_LENGTH |
| /* redirect-port */ |
/* redirect-port */ |
| for(k = 0; k < NM_PORT; k++) { |
for(k = 0; k < NM_PORT; k++) { |
| if(nat->nrpt_id[k]) { | if(nat->nrpt_id[k] == -1) { |
| if (NgSendMsg(gLinksCsock, path, |
if (NgSendMsg(gLinksCsock, path, |
| NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PORT, &nat->nrpt[k], |
NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PORT, &nat->nrpt[k], |
| sizeof(struct ng_nat_redirect_port)) < 0) { |
sizeof(struct ng_nat_redirect_port)) < 0) { |
| Perror("[%s] can't set NAT redirect-port", b->name); |
Perror("[%s] can't set NAT redirect-port", b->name); |
| |
} else { |
| |
if (NgRecvMsg(gLinksCsock, &u.reply, sizeof(u), NULL) < 0) { |
| |
Perror("[%s] can't recv NAT redirect-port message", b->name); |
| |
} else |
| |
nat->nrpt_id[k] = *nat_id; |
| } |
} |
| } |
} |
| } |
} |
| /* redirect-addr */ |
/* redirect-addr */ |
| for(k = 0; k < NM_ADDR; k++) { |
for(k = 0; k < NM_ADDR; k++) { |
| if(nat->nrad_id[k]) { | if(nat->nrad_id[k] == -1) { |
| if (NgSendMsg(gLinksCsock, path, |
if (NgSendMsg(gLinksCsock, path, |
| NGM_NAT_COOKIE, NGM_NAT_REDIRECT_ADDR, &nat->nrad[k], |
NGM_NAT_COOKIE, NGM_NAT_REDIRECT_ADDR, &nat->nrad[k], |
| sizeof(struct ng_nat_redirect_addr)) < 0) { |
sizeof(struct ng_nat_redirect_addr)) < 0) { |
| Perror("[%s] can't set NAT redirect-addr", b->name); |
Perror("[%s] can't set NAT redirect-addr", b->name); |
| |
} else { |
| |
if (NgRecvMsg(gLinksCsock, &u.reply, sizeof(u), NULL) < 0) { |
| |
Perror("[%s] can't recv NAT redirect-addr message", b->name); |
| |
} else |
| |
nat->nrad_id[k] = *nat_id; |
| } |
} |
| } |
} |
| } |
} |
| /* redirect-proto */ |
/* redirect-proto */ |
| for(k = 0; k < NM_PROTO; k++) { |
for(k = 0; k < NM_PROTO; k++) { |
| if(nat->nrpr_id[k]) { | if(nat->nrpr_id[k] == -1) { |
| if (NgSendMsg(gLinksCsock, path, |
if (NgSendMsg(gLinksCsock, path, |
| NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PROTO, &nat->nrpr[k], |
NGM_NAT_COOKIE, NGM_NAT_REDIRECT_PROTO, &nat->nrpr[k], |
| sizeof(struct ng_nat_redirect_proto)) < 0) { |
sizeof(struct ng_nat_redirect_proto)) < 0) { |
| Perror("[%s] can't set NAT redirect-proto", b->name); |
Perror("[%s] can't set NAT redirect-proto", b->name); |
| |
} else { |
| |
if (NgRecvMsg(gLinksCsock, &u.reply, sizeof(u), NULL) < 0) { |
| |
Perror("[%s] can't recv NAT redirect-proto message", b->name); |
| |
} else |
| |
nat->nrpr_id[k] = *nat_id; |
| } |
} |
| } |
} |
| } |
} |
|
Line 2432 static void
|
Line 2675 static void
|
| IfaceShutdownNAT(Bund b) |
IfaceShutdownNAT(Bund b) |
| { |
{ |
| char path[NG_PATHSIZ]; |
char path[NG_PATHSIZ]; |
| |
#ifdef NG_NAT_DESC_LENGTH |
| |
NatState const nat = &b->iface.nat; |
| |
int k; |
| |
#endif |
| |
|
| snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name); |
snprintf(path, sizeof(path), "mpd%d-%s-nat:", gPid, b->name); |
| NgFuncShutdownNode(gLinksCsock, b->name, path); |
NgFuncShutdownNode(gLinksCsock, b->name, path); |
| |
#ifdef NG_NAT_DESC_LENGTH |
| |
/* redirect-port */ |
| |
for(k = 0; k < NM_PORT; k++) |
| |
if(nat->nrpt_id[k] > 0) |
| |
nat->nrpt_id[k] = -1; |
| |
/* redirect-addr */ |
| |
for(k = 0; k < NM_ADDR; k++) |
| |
if(nat->nrad_id[k] > 0) |
| |
nat->nrad_id[k] = -1; |
| |
/* redirect-proto */ |
| |
for(k = 0; k < NM_PROTO; k++) |
| |
if(nat->nrpr_id[k] > 0) |
| |
nat->nrpr_id[k] = -1; |
| |
#endif |
| } |
} |
| #endif /* USE_NG_NAT */ |
#endif /* USE_NG_NAT */ |
| |
|
|
Line 2580 IfaceShutdownIpacct(Bund b)
|
Line 2841 IfaceShutdownIpacct(Bund b)
|
| |
|
| #ifdef USE_NG_NETFLOW |
#ifdef USE_NG_NETFLOW |
| static int |
static int |
| IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out) | IfaceInitNetflow(Bund b, char *path, char *hook, char in, char out, int v6) |
| { |
{ |
| struct ngm_connect cn; |
struct ngm_connect cn; |
| int nif; |
int nif; |
| |
|
| #ifdef NG_NETFLOW_CONF_INGRESS |
#ifdef NG_NETFLOW_CONF_INGRESS |
| nif = gNetflowIface + b->id; | nif = gNetflowIface + b->id*2; |
| #else |
#else |
| nif = gNetflowIface + b->id*2 + out; | nif = gNetflowIface + b->id*4 + out*2; |
| #endif |
#endif |
| |
nif += v6 ? 1 : 0; |
| |
|
| Log(LG_IFACE2, ("[%s] IFACE: Connecting netflow (%s)", b->name, out?"out":"in")); | Log(LG_IFACE2, ("[%s] IFACE: Connecting netflow%s (%s)", |
| | b->name, v6?"6":"", out?"out":"in")); |
| |
|
| /* Create global ng_netflow(4) node if not yet. */ |
/* Create global ng_netflow(4) node if not yet. */ |
| if (gNetflowNodeID == 0) { |
if (gNetflowNodeID == 0) { |
|
Line 2634 IfaceInitNetflow(Bund b, char *path, char *hook, char
|
Line 2897 IfaceInitNetflow(Bund b, char *path, char *hook, char
|
| } |
} |
| |
|
| static int |
static int |
| IfaceSetupNetflow(Bund b, char in, char out) | IfaceSetupNetflow(Bund b, char in, char out, int v6) |
| { |
{ |
| char path[NG_PATHSIZ]; |
char path[NG_PATHSIZ]; |
| struct ng_netflow_setdlt nf_setdlt; |
struct ng_netflow_setdlt nf_setdlt; |
|
Line 2645 IfaceSetupNetflow(Bund b, char in, char out)
|
Line 2908 IfaceSetupNetflow(Bund b, char in, char out)
|
| int nif; |
int nif; |
| |
|
| #ifdef NG_NETFLOW_CONF_INGRESS |
#ifdef NG_NETFLOW_CONF_INGRESS |
| nif = gNetflowIface + b->id; | nif = gNetflowIface + b->id*2; |
| #else |
#else |
| nif = gNetflowIface + b->id*2 + out; | nif = gNetflowIface + b->id*4 + out*2; |
| #endif |
#endif |
| | nif += v6 ? 1 : 0; |
| | |
| /* Configure data link type and interface index. */ |
/* Configure data link type and interface index. */ |
| snprintf(path, sizeof(path), "[%x]:", gNetflowNodeID); |
snprintf(path, sizeof(path), "[%x]:", gNetflowNodeID); |
| nf_setdlt.iface = nif; |
nf_setdlt.iface = nif; |
|
Line 2691 fail:
|
Line 2955 fail:
|
| } |
} |
| |
|
| static void |
static void |
| IfaceShutdownNetflow(Bund b, char in, char out) | IfaceShutdownNetflow(Bund b, char in, char out, int v6) |
| { |
{ |
| char path[NG_PATHSIZ]; |
char path[NG_PATHSIZ]; |
| char hook[NG_HOOKSIZ]; |
char hook[NG_HOOKSIZ]; |
| int nif; |
int nif; |
| |
|
| #ifdef NG_NETFLOW_CONF_INGRESS |
#ifdef NG_NETFLOW_CONF_INGRESS |
| nif = gNetflowIface + b->id; | nif = gNetflowIface + b->id*2; |
| #else |
#else |
| nif = gNetflowIface + b->id*2 + out; | nif = gNetflowIface + b->id*4 + out*2; |
| #endif |
#endif |
| |
nif += v6 ? 1 : 0; |
| |
|
| snprintf(path, NG_PATHSIZ, "[%x]:", gNetflowNodeID); |
snprintf(path, NG_PATHSIZ, "[%x]:", gNetflowNodeID); |
| snprintf(hook, NG_HOOKSIZ, "%s%d", NG_NETFLOW_HOOK_DATA, nif); |
snprintf(hook, NG_HOOKSIZ, "%s%d", NG_NETFLOW_HOOK_DATA, nif); |
|
Line 2817 IfaceSetupMSS(Bund b, uint16_t maxMSS)
|
Line 3082 IfaceSetupMSS(Bund b, uint16_t maxMSS)
|
| memset(&tcpmsscfg, 0, sizeof(tcpmsscfg)); |
memset(&tcpmsscfg, 0, sizeof(tcpmsscfg)); |
| tcpmsscfg.maxMSS = maxMSS; |
tcpmsscfg.maxMSS = maxMSS; |
| |
|
| |
Log(LG_IFACE2, ("[%s] IFACE: Configuring ng_tcpmss %s %u", |
| |
b->name, path, (unsigned)tcpmsscfg.maxMSS)); |
| |
|
| snprintf(tcpmsscfg.inHook, sizeof(tcpmsscfg.inHook), "in"); |
snprintf(tcpmsscfg.inHook, sizeof(tcpmsscfg.inHook), "in"); |
| snprintf(tcpmsscfg.outHook, sizeof(tcpmsscfg.outHook), "out"); |
snprintf(tcpmsscfg.outHook, sizeof(tcpmsscfg.outHook), "out"); |
| if (NgSendMsg(gLinksCsock, path, NGM_TCPMSS_COOKIE, NGM_TCPMSS_CONFIG, |
if (NgSendMsg(gLinksCsock, path, NGM_TCPMSS_COOKIE, NGM_TCPMSS_CONFIG, |
|
Line 2970 IfaceSetupLimits(Bund b)
|
Line 3238 IfaceSetupLimits(Bund b)
|
| struct ngm_connect cn; |
struct ngm_connect cn; |
| int i; |
int i; |
| |
|
| hpu = Malloc(MB_IFACE, sizeof(*hpu)); | hpu = Malloc(MB_ACL, sizeof(*hpu)); |
| hp = &hpu->hprog; |
hp = &hpu->hprog; |
| |
|
| if (b->params.acl_limits[0] || b->params.acl_limits[1]) { |
if (b->params.acl_limits[0] || b->params.acl_limits[1]) { |
|
Line 3016 IfaceSetupLimits(Bund b)
|
Line 3284 IfaceSetupLimits(Bund b)
|
| } |
} |
| |
|
| stathook[0] = 0; |
stathook[0] = 0; |
| memset(hpu, 0, sizeof(hpu)); | memset(hpu, 0, sizeof(*hpu)); |
| /* Prepare filter */ |
/* Prepare filter */ |
| if (strcasecmp(av[0], "all") == 0) { |
if (strcasecmp(av[0], "all") == 0) { |
| hp->bpf_prog_len = MATCH_PROG_LEN; |
hp->bpf_prog_len = MATCH_PROG_LEN; |
|
Line 3040 IfaceSetupLimits(Bund b)
|
Line 3308 IfaceSetupLimits(Bund b)
|
| int bufbraces; |
int bufbraces; |
| |
|
| #define ACL_BUF_SIZE 256*1024 |
#define ACL_BUF_SIZE 256*1024 |
| buf = Malloc(MB_IFACE, ACL_BUF_SIZE); | buf = Malloc(MB_ACL, ACL_BUF_SIZE); |
| buf[0] = 0; |
buf[0] = 0; |
| bufbraces = 0; |
bufbraces = 0; |
| while (f) { |
while (f) { |
| char *b1, *b2, *sbuf; |
char *b1, *b2, *sbuf; |
| sbuf = Mstrdup(MB_IFACE, f->rule); | sbuf = Mstrdup(MB_ACL, f->rule); |
| b2 = sbuf; |
b2 = sbuf; |
| b1 = strsep(&b2, " "); |
b1 = strsep(&b2, " "); |
| if (b2 != NULL) { |
if (b2 != NULL) { |
|
Line 3278 IfaceSetupLimits(Bund b)
|
Line 3546 IfaceSetupLimits(Bund b)
|
| break; |
break; |
| } |
} |
| if (ss == NULL) { |
if (ss == NULL) { |
| ss = Malloc(MB_IFACE, sizeof(*ss)); | ss = Malloc(MB_ACL, sizeof(*ss)); |
| strlcpy(ss->name, l->name, sizeof(ss->name)); |
strlcpy(ss->name, l->name, sizeof(ss->name)); |
| SLIST_INIT(&ss->src); |
SLIST_INIT(&ss->src); |
| SLIST_INSERT_HEAD(&b->iface.ss[dir], ss, next); |
SLIST_INSERT_HEAD(&b->iface.ss[dir], ss, next); |
| } |
} |
| if (stathook[0]) { |
if (stathook[0]) { |
| sss = Malloc(MB_IFACE, sizeof(*sss)); | sss = Malloc(MB_ACL, sizeof(*sss)); |
| strlcpy(sss->hook, stathook, sizeof(sss->hook)); |
strlcpy(sss->hook, stathook, sizeof(sss->hook)); |
| sss->type = SSSS_IN; |
sss->type = SSSS_IN; |
| SLIST_INSERT_HEAD(&ss->src, sss, next); |
SLIST_INSERT_HEAD(&ss->src, sss, next); |
|
Line 3294 IfaceSetupLimits(Bund b)
|
Line 3562 IfaceSetupLimits(Bund b)
|
| for (i = 0; i < 2; i++) { |
for (i = 0; i < 2; i++) { |
| if (inhook[i][0] != 0) { |
if (inhook[i][0] != 0) { |
| if (l->name[0] && !stathook[0]) { |
if (l->name[0] && !stathook[0]) { |
| sss = Malloc(MB_IFACE, sizeof(*sss)); | sss = Malloc(MB_ACL, sizeof(*sss)); |
| strlcpy(sss->hook, inhook[i], sizeof(sss->hook)); |
strlcpy(sss->hook, inhook[i], sizeof(sss->hook)); |
| sss->type = SSSS_MATCH; |
sss->type = SSSS_MATCH; |
| SLIST_INSERT_HEAD(&ss->src, sss, next); |
SLIST_INSERT_HEAD(&ss->src, sss, next); |
|
Line 3392 IfaceGetStats(Bund b, struct svcstat *stat)
|
Line 3660 IfaceGetStats(Bund b, struct svcstat *stat)
|
| break; |
break; |
| } |
} |
| if (!ssr) { |
if (!ssr) { |
| ssr = Malloc(MB_IFACE, sizeof(*ssr)); | ssr = Malloc(MB_ACL, sizeof(*ssr)); |
| strlcpy(ssr->name, ss->name, sizeof(ssr->name)); |
strlcpy(ssr->name, ss->name, sizeof(ssr->name)); |
| SLIST_INSERT_HEAD(&stat->stat[dir], ssr, next); |
SLIST_INSERT_HEAD(&stat->stat[dir], ssr, next); |
| } |
} |
|
Line 3440 IfaceAddStats(struct svcstat *stat1, struct svcstat *s
|
Line 3708 IfaceAddStats(struct svcstat *stat1, struct svcstat *s
|
| break; |
break; |
| } |
} |
| if (!ssr1) { |
if (!ssr1) { |
| ssr1 = Malloc(MB_IFACE, sizeof(*ssr1)); | ssr1 = Malloc(MB_ACL, sizeof(*ssr1)); |
| strlcpy(ssr1->name, ssr2->name, sizeof(ssr1->name)); |
strlcpy(ssr1->name, ssr2->name, sizeof(ssr1->name)); |
| SLIST_INSERT_HEAD(&stat1->stat[dir], ssr1, next); |
SLIST_INSERT_HEAD(&stat1->stat[dir], ssr1, next); |
| } |
} |
|
Line 3486 IfaceSetName(Bund b, const char * ifname)
|
Line 3754 IfaceSetName(Bund b, const char * ifname)
|
| |
|
| /* Get socket */ |
/* Get socket */ |
| if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { |
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { |
| Log(LG_ERR, ("[%s] IFACE: Can't get socket to set name", b->name)); | Perror("[%s] IFACE: Can't get socket to set name", b->name); |
| return(-1); |
return(-1); |
| } |
} |
| |
|
|
Line 3498 IfaceSetName(Bund b, const char * ifname)
|
Line 3766 IfaceSetName(Bund b, const char * ifname)
|
| b->name, iface->ifname, ifname)); |
b->name, iface->ifname, ifname)); |
| |
|
| if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { |
if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { |
| Perror("[%s] IFACE: ioctl(%s, SIOCSIFNAME)", b->name, iface->ifname); | if (errno != EEXIST) { |
| close(s); | Perror("[%s] IFACE: ioctl(%s, SIOCSIFNAME)", b->name, iface->ifname); |
| return(-1); | close(s); |
| | return(-1); |
| | } |
| } |
} |
| |
|
| close(s); |
close(s); |
|
Line 3512 IfaceSetName(Bund b, const char * ifname)
|
Line 3782 IfaceSetName(Bund b, const char * ifname)
|
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| /* |
/* |
| * IfaceSetDescr() |
* IfaceSetDescr() |
| |
* |
| |
* Set/clear our own interface description accessible in console/web interface |
| |
* and kernel level interface description if it is available. |
| |
* |
| |
* Template may contain conversion specifications: |
| |
* |
| |
* %% expands to single % sign; |
| |
* %a for interface local address; |
| |
* %A for peer address; |
| |
* %i for system interface index; |
| |
* %I for interface name; |
| |
* %l for name of bundle's first link |
| |
* %M for peer MAC address of bundle's first link |
| |
* %o for local outer ("physical") address of bundle's first link |
| |
* %O for peer outer ("physical") address of bundle's first link |
| |
* %P for peer outer ("physical") port of bundle's first link |
| |
* %S for interface status (DoD/UP/DOWN) |
| |
* %t for type of bundle's first link (pppoe, pptp, l2tp etc.) |
| |
* %u for self auth name (or dash if self auth name not used) |
| |
* %U for peer auth name (or dash if peer has not authenticated) |
| */ |
*/ |
| |
|
| int |
int |
| IfaceSetDescr(Bund b, const char * ifdescr) | IfaceSetDescr(Bund b, const char * template) |
| { |
{ |
| IfaceState const iface = &b->iface; |
IfaceState const iface = &b->iface; |
| struct ifreq ifr; |
struct ifreq ifr; |
| int s, ifdescr_maxlen; | int s; |
| | unsigned int ifdescr_maxlen = 1024; /* used as limit for old kernels */ |
| char *newdescr; |
char *newdescr; |
| size_t sz = sizeof(int); | size_t sz = sizeof(ifdescr_maxlen); |
| | char *limit, *ifname; |
| | const char *src; |
| | int proceed; |
| | char buf[64]; |
| |
|
| if (b->tmpl) { | static int mib[2] = { -1, 0 }; /* MIB for net.ifdescr_maxlen */ |
| Log(LG_ERR, ("Impossible ioctl(SIOCSIFDESCR) on template")); | size_t miblen = sizeof(mib) / sizeof(mib[0]); |
| return(-1); | |
| | /* |
| | * Check whether running kernel supports interface description. |
| | * Perform the check only once. |
| | */ |
| | if (mib[0] < 0 && sysctlnametomib("net.ifdescr_maxlen", mib, &miblen) < 0) { |
| | mib[0] = 0; |
| | Perror("[%s] IFACE: sysctl net.ifdescr_maxlen failed", b->name); |
| } |
} |
| |
|
| if (sysctlbyname("net.ifdescr_maxlen", &ifdescr_maxlen, &sz, NULL, 0) < 0) { | /* |
| Perror("[%s] IFACE: sysctl net.ifdescr_maxlen failed", b->name); | * Fetch net.ifdescr_maxlen value every time to catch up with changes |
| return(-1); | */ |
| | if (mib[0] && sysctl(mib, 2, &ifdescr_maxlen, &sz, NULL, 0) < 0) { |
| | /* unexpected error from the kernel, use default value */ |
| | Perror("[%s] IFACE: sysctl net.ifdescr_maxlen failed", b->name); |
| | ifdescr_maxlen = 1024; |
| } |
} |
| |
|
| if (ifdescr_maxlen < strlen(ifdescr) + 1) { | newdescr = NULL; |
| Log(LG_ERR, ("[%s] IFACE: Description too long, >%d characters", | ifname = iface->ifname; |
| b->name, ifdescr_maxlen-1)); | if (iface->ifdescr != NULL) { |
| return(-1); | Freee(iface->ifdescr); |
| | iface->ifdescr = NULL; |
| } |
} |
| |
if ((src = template) != NULL) { |
| |
|
| |
/* Will use Mstrdup() later for iface->ifdescr to free extra memory */ |
| |
if ((iface->ifdescr = newdescr = Malloc(MB_IFACE, ifdescr_maxlen)) == NULL) { |
| |
Log(LG_IFACE2, ("[%s] IFACE: no memory for interface %s description", |
| |
b->name, ifname ? ifname : "")); |
| |
return(-1); |
| |
} |
| |
|
| |
/* ifdescr_maxlen includes terminating zero */ |
| |
limit = newdescr + ifdescr_maxlen - 1; |
| |
|
| |
/* |
| |
* Perform template expansion |
| |
*/ |
| |
proceed = 1; |
| |
while (proceed && *src && newdescr < limit) { |
| |
if (*src != '%') { /* ordinary symbol, just copy it and proceed */ |
| |
*newdescr++ = *src++; |
| |
continue; |
| |
} |
| |
if (!*(src+1)) { /* '%' at the end of template, just copy */ |
| |
*newdescr++ = *src++; |
| |
continue; |
| |
} |
| |
switch(*++src) { /* expand */ |
| |
case '%': /* %% got replaced with single % */ |
| |
*newdescr++ = *src; |
| |
break; |
| |
|
| |
#define DST_COPY(a) \ |
| |
do { const char *temp = a; \ |
| |
if (temp && *temp) { \ |
| |
if ((newdescr + strlen (temp)) <= limit) {\ |
| |
newdescr = stpcpy (newdescr, temp); \ |
| |
} else { \ |
| |
proceed = 0; \ |
| |
} \ |
| |
} else { \ |
| |
*newdescr++ = '-'; \ |
| |
} \ |
| |
} while(0) |
| |
|
| |
/* self address */ |
| |
case 'a': |
| |
{ |
| |
char *sep; |
| |
u_rangetoa(&iface->self_addr, buf, sizeof(buf)); |
| |
/* cut netmask */ |
| |
if ((sep = strchr(buf, '/'))) |
| |
*sep = '\0'; |
| |
DST_COPY(buf); |
| |
} |
| |
break; |
| |
/* peer address */ |
| |
case 'A': |
| |
{ |
| |
u_addrtoa(&iface->peer_addr, buf, sizeof(buf)); |
| |
DST_COPY(buf); |
| |
} |
| |
break; |
| |
/* interface index */ |
| |
case 'i': |
| |
{ |
| |
snprintf(buf, sizeof(buf), "%u", iface->ifindex); |
| |
DST_COPY(buf); |
| |
} |
| |
break; |
| |
/* interface name */ |
| |
case 'I': |
| |
DST_COPY(iface->ifname); |
| |
break; |
| |
/* first link name */ |
| |
case 'l': |
| |
DST_COPY(b->links[0] ? b->links[0]->name : NULL); |
| |
break; |
| |
/* peer MAC address */ |
| |
case 'M': |
| |
if (b->links[0]) { |
| |
PhysType const pt = b->links[0]->type; |
| |
if (pt && pt->peermacaddr) { |
| |
(*pt->peermacaddr)(b->links[0], buf, sizeof(buf)); |
| |
DST_COPY(buf); |
| |
} else { |
| |
DST_COPY("-"); |
| |
} |
| |
} else { |
| |
DST_COPY("-"); |
| |
} |
| |
break; |
| |
/* local "physycal" address */ |
| |
case 'o': |
| |
if (b->links[0] && PhysGetSelfAddr(b->links[0], buf, sizeof(buf)) == 0) { |
| |
DST_COPY(buf); |
| |
} else { |
| |
DST_COPY("-"); |
| |
} |
| |
break; |
| |
/* peer "physycal" address */ |
| |
case 'O': |
| |
if (b->links[0] && PhysGetPeerAddr(b->links[0], buf, sizeof(buf)) == 0) { |
| |
DST_COPY(buf); |
| |
} else { |
| |
DST_COPY("-"); |
| |
} |
| |
break; |
| |
/* peer port */ |
| |
case 'P': |
| |
if (b->links[0] && PhysGetPeerPort(b->links[0], buf, sizeof(buf)) == 0) { |
| |
DST_COPY(buf); |
| |
} else { |
| |
DST_COPY("-"); |
| |
} |
| |
break; |
| |
/* interface status */ |
| |
case 'S': |
| |
DST_COPY(iface->up ? (iface->dod ? "DoD" : "UP") : "DOWN"); |
| |
break; |
| |
/* first link type */ |
| |
case 't': |
| |
DST_COPY(b->links[0] ? b->links[0]->type->name : NULL); |
| |
break; |
| |
/* self auth name */ |
| |
case 'u': |
| |
DST_COPY(b->links[0] ? b->links[0]->lcp.auth.conf.authname : NULL); |
| |
break; |
| |
/* peer auth name */ |
| |
case 'U': |
| |
DST_COPY(b->params.authname); |
| |
break; |
| |
#undef DST_COPY |
| |
default: /* unrecognized specification, just copy */ |
| |
*newdescr++ = '%'; |
| |
if (newdescr < limit) |
| |
*newdescr++ = *src; |
| |
} /* switch(*++src) */ |
| |
++src; |
| |
} /* while */ |
| |
*newdescr = '\0'; |
| |
|
| |
/* includes terminating zero */ |
| |
sz = newdescr - iface->ifdescr + 1; |
| |
if ((newdescr = Mstrdup(MB_IFACE, iface->ifdescr)) == NULL) { |
| |
Log(LG_IFACE2, ("[%s] IFACE: no memory for interface %s description", |
| |
b->name, ifname ? ifname : "")); |
| |
Freee(iface->ifdescr); |
| |
iface->ifdescr = NULL; |
| |
return(-1); |
| |
} |
| |
Freee(iface->ifdescr); |
| |
iface->ifdescr = newdescr; |
| |
} /* template != NULL */ |
| |
|
| |
/* Set description of interface */ |
| |
if (mib[0] == 0) |
| |
return(0); /* do not bother kernel if it is too old */ |
| |
|
| |
if (ifname == NULL || *ifname == '\0') |
| |
return(0); /* we have not set system interface name yet */ |
| |
|
| /* Get socket */ |
/* Get socket */ |
| if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { |
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { |
| Log(LG_ERR, ("[%s] IFACE: Can't get socket to set description", b->name)); | Perror("[%s] IFACE: Can't get socket to set description for %s", |
| | b->name, ifname); |
| return(-1); |
return(-1); |
| } |
} |
| |
|
| /* Set description of interface */ |
|
| memset(&ifr, 0, sizeof(ifr)); |
memset(&ifr, 0, sizeof(ifr)); |
| strlcpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name)); | strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); |
| ifr.ifr_buffer.length = strlen(ifdescr) + 1; | |
| if (ifr.ifr_buffer.length == 1) { | if (!newdescr || !*newdescr) { /* empty description or clearing request */ |
| ifr.ifr_buffer.buffer = newdescr = NULL; | ifr.ifr_buffer.buffer = NULL; |
| ifr.ifr_buffer.length = 0; |
ifr.ifr_buffer.length = 0; |
| Log(LG_IFACE2, ("[%s] IFACE: clearing \"%s\" description", |
Log(LG_IFACE2, ("[%s] IFACE: clearing \"%s\" description", |
| b->name, iface->ifname)); | b->name, ifname)); |
| } else { |
} else { |
| newdescr = Mstrdup(MB_IFACE, ifdescr); | ifr.ifr_buffer.length = (unsigned)sz; |
| ifr.ifr_buffer.buffer = newdescr; |
ifr.ifr_buffer.buffer = newdescr; |
| Log(LG_IFACE2, ("[%s] IFACE: setting \"%s\" description to \"%s\"", |
Log(LG_IFACE2, ("[%s] IFACE: setting \"%s\" description to \"%s\"", |
| b->name, iface->ifname, ifdescr)); | b->name, ifname, newdescr)); |
| } |
} |
| |
|
| if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) { |
if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) { |
| Perror("[%s] IFACE: ioctl(%s, SIOCSIFDESCR)", b->name, iface->ifname); | Perror("[%s] IFACE: ioctl(%s, SIOCSIFDESCR, \"%s\")", |
| Freee(newdescr); | b->name, ifname, newdescr ? newdescr : "" ); |
| close(s); |
close(s); |
| return(-1); |
return(-1); |
| } |
} |
| Freee(newdescr); |
|
| close(s); |
close(s); |
| return(0); |
return(0); |
| } |
} |