diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2013-08-31 23:05:29 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2013-08-31 23:05:29 +0400 |
commit | 4990a892f474fba052bd884aa8f4c072e6a42c5e (patch) | |
tree | ac96d8d0afffab027321b9483aedc388bcf83d7c /accel-pppd/libnetlink | |
parent | 50244b414c64064bbfd91531d6cc694a96e241af (diff) | |
download | accel-ppp-4990a892f474fba052bd884aa8f4c072e6a42c5e.tar.gz accel-ppp-4990a892f474fba052bd884aa8f4c072e6a42c5e.zip |
ipoe: fixed race during receiving relay reply
Diffstat (limited to 'accel-pppd/libnetlink')
-rw-r--r-- | accel-pppd/libnetlink/iputils.c | 83 | ||||
-rw-r--r-- | accel-pppd/libnetlink/iputils.h | 3 |
2 files changed, 85 insertions, 1 deletions
diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c index 029d09a6..71c14e28 100644 --- a/accel-pppd/libnetlink/iputils.c +++ b/accel-pppd/libnetlink/iputils.c @@ -119,7 +119,7 @@ int __export iplink_get_stats(int ifindex, struct rtnl_link_stats *stats) struct iplink_req { struct nlmsghdr n; struct ifinfomsg i; - char buf[4096]; + char buf[1024]; } req; struct ifinfomsg *ifi; int len; @@ -161,6 +161,87 @@ int __export iplink_get_stats(int ifindex, struct rtnl_link_stats *stats) return 0; } + +int iplink_vlan_add(const char *ifname, int ifindex, int vid) +{ + struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char buf[1024]; + } req; + struct rtattr *linkinfo, *data; + + if (!rth) + open_rth(); + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 1024); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL; + req.n.nlmsg_type = RTM_NEWLINK; + req.i.ifi_family = AF_UNSPEC; + + addattr_l(&req.n, 1024, IFLA_LINK, &ifindex, 4); + addattr_l(&req.n, 1024, IFLA_IFNAME, ifname, strlen(ifname)); + + linkinfo = NLMSG_TAIL(&req.n); + addattr_l(&req.n, 1024, IFLA_LINKINFO, NULL, 0); + addattr_l(&req.n, 1024, IFLA_INFO_KIND, "vlan", 4); + + data = NLMSG_TAIL(&req.n); + addattr_l(&req.n, 1024, IFLA_INFO_DATA, NULL, 0); + addattr_l(&req.n, 1024, IFLA_VLAN_ID, &vid, 2); + data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; + + linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; + + if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) + return -1; + + return 0; +} + +int iplink_vlan_del(int ifindex) +{ + struct iplink_req { + struct nlmsghdr n; + struct ifinfomsg i; + char buf[1024]; + } req; + struct rtattr *linkinfo; + + if (!rth) + open_rth(); + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 1024); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + req.n.nlmsg_type = RTM_DELLINK; + req.i.ifi_family = AF_UNSPEC; + req.i.ifi_index = ifindex; + + linkinfo = NLMSG_TAIL(&req.n); + addattr_l(&req.n, 1024, IFLA_LINKINFO, NULL, 0); + addattr_l(&req.n, 1024, IFLA_INFO_KIND, "vlan", 4); + + /*data = NLMSG_TAIL(&req.n); + addattr_l(&req.n, 1024, IFLA_VLAN_ID, &vid, 2); + data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data;*/ + + linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; + + if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) + return -1; + + return 0; +} int __export ipaddr_add(int ifindex, in_addr_t addr, int mask) { diff --git a/accel-pppd/libnetlink/iputils.h b/accel-pppd/libnetlink/iputils.h index 5baf7426..2657a5c9 100644 --- a/accel-pppd/libnetlink/iputils.h +++ b/accel-pppd/libnetlink/iputils.h @@ -8,6 +8,9 @@ typedef int (*iplink_list_func)(int index, int flags, const char *name, void *ar int iplink_list(iplink_list_func func, void *arg); 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 ipaddr_add(int ifindex, in_addr_t addr, int mask); int ipaddr_del(int ifindex, in_addr_t addr); |