diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2015-11-18 18:43:30 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2015-11-18 18:43:30 +0300 |
commit | decb3de44c59f789e49250c4d2791e4219078b54 (patch) | |
tree | 27c80ce7be931a4372e13bbdb253d059dabef2e5 /accel-pppd | |
parent | 1e505332a84bef2857f07155f0c188742303be76 (diff) | |
download | accel-ppp-decb3de44c59f789e49250c4d2791e4219078b54.tar.gz accel-ppp-decb3de44c59f789e49250c4d2791e4219078b54.zip |
ipoe: for vlan name pattern implemented %P argument - VID of parent interface
Diffstat (limited to 'accel-pppd')
-rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 3 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 19 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 1 | ||||
-rw-r--r-- | accel-pppd/libnetlink/iputils.c | 54 | ||||
-rw-r--r-- | accel-pppd/libnetlink/iputils.h | 1 |
5 files changed, 73 insertions, 5 deletions
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 8923b06f..648fd247 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -386,6 +386,9 @@ Specifies pattern of vlan interface name. Pattern may contain following macros: .B %N - number of vlan. .br +.B %P +- number of vlan of parent interface. +.br By default vlan-name=%I.%N. .TP .BI "soft-terminate=" 0|1 diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index 61e040eb..594df29e 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -2205,13 +2205,14 @@ static int get_offer_delay() return 0; } -static int make_vlan_name(const char *parent, int vid, char *name) +static int make_vlan_name(const char *parent, int svid, int cvid, char *name) { char *ptr1 = name, *endptr = name + IFNAMSIZ; const char *ptr2 = conf_vlan_name; - char num[5], *ptr3 = num; + char svid_str[5], cvid_str[5], *ptr3; - sprintf(num, "%i", vid); + sprintf(svid_str, "%i", svid); + sprintf(cvid_str, "%i", cvid); while (ptr1 < endptr && *ptr2) { if (ptr2[0] == '%' && ptr2[1] == 'I') { @@ -2219,6 +2220,12 @@ static int make_vlan_name(const char *parent, int vid, char *name) *ptr1++ = *parent++; ptr2 += 2; } else if (ptr2[0] == '%' && ptr2[1] == 'N') { + ptr3 = cvid_str; + while (ptr1 < endptr && *ptr3) + *ptr1++ = *ptr3++; + ptr2 += 2; + } else if (ptr2[0] == '%' && ptr2[1] == 'P') { + ptr3 = svid_str; while (ptr1 < endptr && *ptr3) *ptr1++ = *ptr3++; ptr2 += 2; @@ -2240,7 +2247,7 @@ void ipoe_vlan_notify(int ifindex, int vid) struct conf_option_t *opt; struct ifreq ifr; char *ptr; - int len, r; + int len, r, svid; pcre *re = NULL; const char *pcre_err; char *pattern; @@ -2257,7 +2264,9 @@ void ipoe_vlan_notify(int ifindex, int vid) return; } - if (make_vlan_name(ifr.ifr_name, vid, ifname)) { + svid = iplink_vlan_get_vid(ifindex); + + if (make_vlan_name(ifr.ifr_name, svid, vid, ifname)) { log_error("ipoe: vlan-mon: %s.%i: interface name is too long\n", ifr.ifr_name, vid); return; } diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index f2331039..1405092e 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -35,6 +35,7 @@ struct ipoe_serv { pthread_mutex_t lock; int parent_ifindex; int vid; + int parent_vid; int opt_mode; uint32_t opt_src; int opt_arp; diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c index 480f028f..7dbdf677 100644 --- a/accel-pppd/libnetlink/iputils.c +++ b/accel-pppd/libnetlink/iputils.c @@ -243,6 +243,60 @@ int __export iplink_vlan_del(int ifindex) return 0; } +int __export iplink_vlan_get_vid(int ifindex) +{ + struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char buf[4096]; + } req; + struct ifinfomsg *ifi; + int len; + struct rtattr *tb[IFLA_MAX + 1]; + + if (!rth) + open_rth(); + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 4096); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + req.n.nlmsg_type = RTM_GETLINK; + req.i.ifi_family = AF_PACKET; + req.i.ifi_index = ifindex; + + if (rtnl_talk(rth, &req.n, 0, 0, &req.n, NULL, NULL, 0) < 0) + return -1; + + if (req.n.nlmsg_type != RTM_NEWLINK) + return -1; + + ifi = NLMSG_DATA(&req.n); + + len = req.n.nlmsg_len; + + len -= NLMSG_LENGTH(sizeof(*ifi)); + if (len < 0) + return -1; + + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); + + if (!tb[IFLA_LINKINFO]) + return 0; + + parse_rtattr_nested(tb, IFLA_MAX, tb[IFLA_LINKINFO]); + + if (strcmp(RTA_DATA(tb[IFLA_INFO_KIND]), "vlan")) + return 0; + + parse_rtattr_nested(tb, IFLA_MAX, tb[IFLA_INFO_DATA]); + return *(uint16_t *)RTA_DATA(tb[IFLA_VLAN_ID]); +} + + int __export ipaddr_add(int ifindex, in_addr_t addr, int mask) { struct ipaddr_req { diff --git a/accel-pppd/libnetlink/iputils.h b/accel-pppd/libnetlink/iputils.h index 60976277..c0889a71 100644 --- a/accel-pppd/libnetlink/iputils.h +++ b/accel-pppd/libnetlink/iputils.h @@ -10,6 +10,7 @@ int iplink_get_stats(int ifindex, struct rtnl_link_stats *stats); int iplink_vlan_add(const char *ifname, int ifindex, int vid); int iplink_vlan_del(int ifindex); +int iplink_vlan_get_vid(int ifindex); int ipaddr_add(int ifindex, in_addr_t addr, int mask); int ipaddr_del(int ifindex, in_addr_t addr, int mask); |