diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2016-03-17 22:24:19 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2016-03-17 22:24:26 +0300 |
commit | cc9e2a49061b2a77a51e27ed23c8040626a2083b (patch) | |
tree | a906d60e21d789d9d7a88825ada70be0622ecca4 /accel-pppd/ctrl/pppoe/pppoe.c | |
parent | ea7f988b40c03a21571143be30200f77450f3ba4 (diff) | |
download | accel-ppp-xebd-cc9e2a49061b2a77a51e27ed23c8040626a2083b.tar.gz accel-ppp-xebd-cc9e2a49061b2a77a51e27ed23c8040626a2083b.zip |
vlan_mon,ipoe,pppoe: implemented detection of vlan existance
Diffstat (limited to 'accel-pppd/ctrl/pppoe/pppoe.c')
-rw-r--r-- | accel-pppd/ctrl/pppoe/pppoe.c | 74 |
1 files changed, 64 insertions, 10 deletions
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c index f219152..b649b0b 100644 --- a/accel-pppd/ctrl/pppoe/pppoe.c +++ b/accel-pppd/ctrl/pppoe/pppoe.c @@ -1351,6 +1351,19 @@ static void __pppoe_server_start(const char *ifname, const char *opt, void *cli, } strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + if (net->sock_ioctl(SIOCGIFFLAGS, &ifr)) { + if (cli) + cli_sendv(cli, "%s: %s\r\n", ifname, strerror(errno)); + log_error("pppoe: %s: %s\n", ifname, strerror(errno)); + goto out_err; + } + + if (!ifr.ifr_flags & IFF_UP) { + ifr.ifr_flags |= IFF_UP; + net->sock_ioctl(SIOCSIFFLAGS, &ifr); + } + if (net->sock_ioctl(SIOCGIFHWADDR, &ifr)) { if (cli) cli_sendv(cli, "ioctl(SIOCGIFHWADDR): %s\r\n", strerror(errno)); @@ -1526,7 +1539,7 @@ static int init_secret(struct pppoe_serv_t *serv) return 0; } -void pppoe_vlan_mon_notify(int ifindex, int vid) +void pppoe_vlan_mon_notify(int ifindex, int vid, int vlan_ifindex) { struct conf_sect_t *sect = conf_get_section("pppoe"); struct conf_option_t *opt; @@ -1556,17 +1569,53 @@ void pppoe_vlan_mon_notify(int ifindex, int vid) return; } - strcpy(ifr.ifr_name, ifname); - len = strlen(ifr.ifr_name); + if (vlan_ifindex) { + struct pppoe_serv_t *serv; - if (iplink_vlan_add(ifr.ifr_name, ifindex, vid)) - return; + pthread_rwlock_rdlock(&serv_lock); + list_for_each_entry(serv, &serv_list, entry) { + if (serv->ifindex == vlan_ifindex) { + pthread_rwlock_unlock(&serv_lock); + return; + } + } + pthread_rwlock_unlock(&serv_lock); + + log_info2("pppoe: create vlan %s parent %s\n", ifname, ifr.ifr_name); + + ifr.ifr_ifindex = vlan_ifindex; + if (ioctl(sock_fd, SIOCGIFNAME, &ifr, sizeof(ifr))) { + log_error("pppoe: vlan-mon: failed to get interface name, ifindex=%i\n", ifindex); + return; + } - log_info2("pppoe: create vlan %s parent %s\n", ifname, ifr.ifr_name); + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr, sizeof(ifr))) + return; + + if (ifr.ifr_flags & IFF_UP) { + ifr.ifr_flags &= ~IFF_UP; + + if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr, sizeof(ifr))) + return; + } + + if (strcmp(ifr.ifr_name, ifname)) { + strcpy(ifr.ifr_newname, ifname); + if (ioctl(sock_fd, SIOCSIFNAME, &ifr, sizeof(ifr))) { + log_error("pppoe: vlan-mon: failed to rename interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname); + return; + } + strcpy(ifr.ifr_name, ifname); + } + } else { + log_info2("pppoe: create vlan %s parent %s\n", ifname, ifr.ifr_name); - ioctl(sock_fd, SIOCGIFFLAGS, &ifr, sizeof(ifr)); - ifr.ifr_flags |= IFF_UP; - ioctl(sock_fd, SIOCSIFFLAGS, &ifr, sizeof(ifr)); + if (iplink_vlan_add(ifr.ifr_name, ifindex, vid)) + return; + } + + strcpy(ifr.ifr_name, ifname); + len = strlen(ifname); if (ioctl(sock_fd, SIOCGIFINDEX, &ifr, sizeof(ifr))) { log_error("pppoe: vlan-mon: %s: failed to get interface index\n", ifr.ifr_name); @@ -1602,9 +1651,14 @@ void pppoe_vlan_mon_notify(int ifindex, int vid) continue; __pppoe_server_start(ifr.ifr_name, opt->val, NULL, ifindex, vid); - } else if (ptr - opt->val == len && memcmp(opt->val, ifr.ifr_name, len) == 0) + return; + } else if (ptr - opt->val == len && memcmp(opt->val, ifr.ifr_name, len) == 0) { __pppoe_server_start(ifr.ifr_name, opt->val, NULL, ifindex, vid); + return; + } } + + log_warn("pppoe: vlan %s not started\n", ifname); } static void add_vlan_mon(const char *opt, long *mask) |