diff options
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 122 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.h | 4 | ||||
-rw-r--r-- | accel-pppd/ifcfg.c | 163 | ||||
-rw-r--r-- | accel-pppd/include/ap_session.h | 1 | ||||
-rw-r--r-- | accel-pppd/libnetlink/iplink.c | 138 | ||||
-rw-r--r-- | accel-pppd/libnetlink/iplink.h | 5 | ||||
-rw-r--r-- | drivers/ipoe/ipoe.c | 38 |
7 files changed, 374 insertions, 97 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index ae4dca20..69ffe36c 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -13,6 +13,7 @@ #include <sys/socket.h> #include <sys/ioctl.h> #include <linux/if.h> +#include <linux/route.h> #include <pcre.h> @@ -44,6 +45,7 @@ static int conf_dhcpv4 = 1; static int conf_up = 0; static int conf_mode = 0; static int conf_shared = 1; +static int conf_ifcfg = 1; //static int conf_dhcpv6; static int conf_username; static int conf_unit_cache; @@ -66,6 +68,13 @@ static mempool_t ses_pool; static LIST_HEAD(serv_list); +struct ifaddr +{ + struct list_head entry; + in_addr_t addr; + int refs; +}; + struct iplink_arg { pcre *re; @@ -180,9 +189,10 @@ static void ipoe_session_start(struct ipoe_session *ses) struct ifreq ifr; struct unit_cache *uc; - if (ses->serv->opt_shared == 0) + if (ses->serv->opt_shared == 0 && (!ses->ses.ipv4 || ses->ses.ipv4->peer_addr == ses->yiaddr)) { strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN); - else if (ses->ifindex == -1) { + ses->ses.ifindex = ses->serv->ifindex; + } else if (ses->ifindex == -1) { pthread_mutex_lock(&uc_lock); if (!list_empty(&uc_list)) { uc = list_entry(uc_list.next, typeof(*uc), entry); @@ -246,6 +256,10 @@ static void ipoe_session_start(struct ipoe_session *ses) return; } + dhcpv4_get_ip(ses->serv->dhcpv4, &ses->yiaddr, &ses->siaddr, &ses->mask); + if (ses->yiaddr) + ses->dhcp_addr = 1; + ses->ses.ipv4 = ipdb_get_ipv4(&ses->ses); /*if (!ses->ses.ipv4) { log_ppp_warn("no free IPv4 address\n"); @@ -289,14 +303,93 @@ static void ipoe_session_start(struct ipoe_session *ses) } } +static void ipoe_ifcfg_add(struct ipoe_session *ses) +{ + struct ifaddr *a; + struct ipoe_serv *serv = ses->serv; + int f = 0; + + pthread_mutex_lock(&serv->lock); + + if (ses->serv->opt_shared) { + list_for_each_entry(a, &serv->addr_list, entry) { + if (a->addr == ses->siaddr) { + f = 1; + break; + } + } + if (!f) { + a = _malloc(sizeof(*a)); + a->addr = ses->siaddr; + a->refs = 1; + list_add_tail(&a->entry, &serv->addr_list); + + if (ipaddr_add(serv->ifindex, a->addr, 32)) + log_ppp_warn("ipoe: failed to add addess to interface '%s'\n", serv->ifname); + } else + a->refs++; + } else { + if (ipaddr_add(serv->ifindex, ses->siaddr, 32)) + log_ppp_warn("ipoe: failed to add addess to interface '%s'\n", serv->ifname); + } + + pthread_mutex_unlock(&serv->lock); + + if (iproute_add(serv->ifindex, ses->siaddr, ses->yiaddr)) + log_ppp_warn("ipoe: failed to add route to interface '%s'\n", serv->ifname); + + ses->ifcfg = 1; +} + +static void ipoe_ifcfg_del(struct ipoe_session *ses) +{ + struct ifaddr *a; + struct ipoe_serv *serv = ses->serv; + + if (iproute_del(serv->ifindex, ses->yiaddr)) + log_ppp_warn("ipoe: failed to delete route from interface '%s'\n", serv->ifname); + + pthread_mutex_lock(&serv->lock); + + if (ses->serv->opt_shared) { + list_for_each_entry(a, &serv->addr_list, entry) { + if (a->addr == ses->siaddr) + break; + } + if (--a->refs == 0) { + if (ipaddr_del(serv->ifindex, a->addr)) + log_ppp_warn("ipoe: failed to delete addess from interface '%s'\n", serv->ifname); + list_del(&a->entry); + _free(a); + } + } else { + if (ipaddr_del(serv->ifindex, ses->siaddr)) + log_ppp_warn("ipoe: failed to add addess to interface '%s'\n", serv->ifname); + } + + pthread_mutex_unlock(&serv->lock); +} + static void ipoe_session_activate(struct ipoe_session *ses) { + uint32_t addr; + if (ses->ifindex != -1) { - if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, ses->ses.ipv4->peer_addr, NULL, NULL)) { + if (!ses->ses.ipv4) + addr = 1; + else if (ses->ses.ipv4->peer_addr != ses->yiaddr) + addr = ses->ses.ipv4->peer_addr; + else + addr = 0; + if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, addr, NULL, NULL)) { ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 0); return; } - } + } else + ses->ctrl.dont_ifcfg = 1; + + if (ses->serv->opt_ifcfg) + ipoe_ifcfg_add(ses); ap_session_activate(&ses->ses); @@ -387,9 +480,12 @@ static void ipoe_session_finished(struct ap_session *s) serv_close = ses->serv->need_close && list_empty(&ses->serv->sessions); pthread_mutex_unlock(&ses->serv->lock); - if (ses->yiaddr && ses->serv->dhcpv4 && ses->serv->dhcpv4->range) + if (ses->dhcp_addr) dhcpv4_put_ip(ses->serv->dhcpv4, ses->yiaddr); + if (ses->ifcfg) + ipoe_ifcfg_del(ses); + if (serv_close) ipoe_serv_close(&ses->serv->ctx); @@ -436,8 +532,6 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s memcpy(ses->hwaddr, pack->hdr->chaddr, 6); ses->giaddr = pack->hdr->giaddr; - dhcpv4_get_ip(serv->dhcpv4, &ses->yiaddr, &ses->siaddr, &ses->mask); - if (pack->agent_circuit_id) dlen += sizeof(struct dhcp_opt) + pack->agent_circuit_id->len; @@ -797,6 +891,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) int opt_dhcpv4 = 0; int opt_up = 0; int opt_mode = conf_mode; + int opt_ifcfg = conf_ifcfg; str0 = strchr(opt, ','); if (str0) { @@ -837,6 +932,8 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) opt_mode = MODE_L3; else goto parse_err; + } else if (strcmp(str, "ifcfg") == 0) { + opt_ifcfg = atoi(ptr1); } if (end) @@ -875,7 +972,8 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) } serv->opt_up = opt_up; - serv->opt_mode = conf_mode; + serv->opt_mode = opt_mode; + serv->opt_ifcfg = opt_ifcfg; return; } @@ -889,8 +987,10 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) serv->opt_dhcpv4 = opt_dhcpv4; serv->opt_up = opt_up; serv->opt_mode = opt_mode; + serv->opt_ifcfg = opt_ifcfg; serv->active = 1; INIT_LIST_HEAD(&serv->sessions); + INIT_LIST_HEAD(&serv->addr_list); pthread_mutex_init(&serv->lock, NULL); triton_context_register(&serv->ctx, NULL); @@ -1116,6 +1216,12 @@ static void load_config(void) else conf_shared = 1; + opt = conf_get_opt("ipoe", "ifcfg"); + if (opt) + conf_ifcfg = atoi(opt); + else + conf_ifcfg = 1; + opt = conf_get_opt("ipoe", "mode"); if (opt) { if (!strcmp(opt, "L2")) diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h index d18db698..edf97540 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.h +++ b/accel-pppd/ctrl/ipoe/ipoe.h @@ -16,12 +16,14 @@ struct ipoe_serv int ifindex; int active; struct list_head sessions; + struct list_head addr_list; struct dhcpv4_serv *dhcpv4; pthread_mutex_t lock; int opt_mode; int opt_shared:1; int opt_dhcpv4:1; int opt_up:1; + int opt_ifcfg:1; int need_close:1; }; @@ -51,6 +53,8 @@ struct ipoe_session uint8_t *data; struct dhcpv4_packet *dhcpv4_request; int ifindex; + int ifcfg:1; + int dhcp_addr:1; }; struct ipoe_session_info diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c index 0b4927b6..ac88a0d1 100644 --- a/accel-pppd/ifcfg.c +++ b/accel-pppd/ifcfg.c @@ -71,104 +71,106 @@ void ap_session_ifup(struct ap_session *ses) if (ses->stop_time) return; - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, ses->ifname); + if (!ses->ctrl->dont_ifcfg) { + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, ses->ifname); #ifdef USE_BACKUP - if (!ses->backup || !ses->backup->internal) { + if (!ses->backup || !ses->backup->internal) { #endif - if (ses->ipv4) { - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = ses->ipv4->addr; - memcpy(&ifr.ifr_addr, &addr, sizeof(addr)); - - if (ioctl(sock_fd, SIOCSIFADDR, &ifr)) - log_ppp_error("failed to set IPv4 address: %s\n", strerror(errno)); - - /*if (ses->ctrl->type == CTRL_TYPE_IPOE) { - addr.sin_addr.s_addr = 0xffffffff; - memcpy(&ifr.ifr_netmask, &addr, sizeof(addr)); - if (ioctl(sock_fd, SIOCSIFNETMASK, &ifr)) - log_ppp_error("failed to set IPv4 nask: %s\n", strerror(errno)); - }*/ + if (ses->ipv4) { + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = ses->ipv4->addr; + memcpy(&ifr.ifr_addr, &addr, sizeof(addr)); + + if (ioctl(sock_fd, SIOCSIFADDR, &ifr)) + log_ppp_error("failed to set IPv4 address: %s\n", strerror(errno)); - addr.sin_addr.s_addr = ses->ipv4->peer_addr; - - /*if (ses->ctrl->type == CTRL_TYPE_IPOE) { - memset(&rt, 0, sizeof(rt)); - memcpy(&rt.rt_dst, &addr, sizeof(addr)); - rt.rt_flags = RTF_HOST | RTF_UP; - rt.rt_metric = 1; - rt.rt_dev = ifr.ifr_name; - if (ioctl(sock_fd, SIOCADDRT, &rt, sizeof(rt))) - log_ppp_error("failed to add route: %s\n", strerror(errno)); - } else*/ { - memcpy(&ifr.ifr_dstaddr, &addr, sizeof(addr)); + /*if (ses->ctrl->type == CTRL_TYPE_IPOE) { + addr.sin_addr.s_addr = 0xffffffff; + memcpy(&ifr.ifr_netmask, &addr, sizeof(addr)); + if (ioctl(sock_fd, SIOCSIFNETMASK, &ifr)) + log_ppp_error("failed to set IPv4 nask: %s\n", strerror(errno)); + }*/ - if (ioctl(sock_fd, SIOCSIFDSTADDR, &ifr)) - log_ppp_error("failed to set peer IPv4 address: %s\n", strerror(errno)); + addr.sin_addr.s_addr = ses->ipv4->peer_addr; + + /*if (ses->ctrl->type == CTRL_TYPE_IPOE) { + memset(&rt, 0, sizeof(rt)); + memcpy(&rt.rt_dst, &addr, sizeof(addr)); + rt.rt_flags = RTF_HOST | RTF_UP; + rt.rt_metric = 1; + rt.rt_dev = ifr.ifr_name; + if (ioctl(sock_fd, SIOCADDRT, &rt, sizeof(rt))) + log_ppp_error("failed to add route: %s\n", strerror(errno)); + } else*/ { + memcpy(&ifr.ifr_dstaddr, &addr, sizeof(addr)); + + if (ioctl(sock_fd, SIOCSIFDSTADDR, &ifr)) + log_ppp_error("failed to set peer IPv4 address: %s\n", strerror(errno)); + } } - } - - if (ses->ipv6) { - devconf(ses, "accept_ra", "0"); - devconf(ses, "autoconf", "0"); - devconf(ses, "forwarding", "1"); - memset(&ifr6, 0, sizeof(ifr6)); - - if (ses->ctrl->type != CTRL_TYPE_IPOE) { - ifr6.ifr6_addr.s6_addr32[0] = htons(0xfe80); - *(uint64_t *)(ifr6.ifr6_addr.s6_addr + 8) = ses->ipv6->intf_id; - ifr6.ifr6_prefixlen = 64; - ifr6.ifr6_ifindex = ses->ifindex; + if (ses->ipv6) { + devconf(ses, "accept_ra", "0"); + devconf(ses, "autoconf", "0"); + devconf(ses, "forwarding", "1"); - if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6)) - log_ppp_error("faild to set LL IPv6 address: %s\n", strerror(errno)); - } - - list_for_each_entry(a, &ses->ipv6->addr_list, entry) { - if (a->prefix_len == 128) - continue; + memset(&ifr6, 0, sizeof(ifr6)); + + if (ses->ctrl->type != CTRL_TYPE_IPOE) { + ifr6.ifr6_addr.s6_addr32[0] = htons(0xfe80); + *(uint64_t *)(ifr6.ifr6_addr.s6_addr + 8) = ses->ipv6->intf_id; + ifr6.ifr6_prefixlen = 64; + ifr6.ifr6_ifindex = ses->ifindex; + + if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6)) + log_ppp_error("faild to set LL IPv6 address: %s\n", strerror(errno)); + } + + list_for_each_entry(a, &ses->ipv6->addr_list, entry) { + if (a->prefix_len == 128) + continue; - build_addr(a, ses->ipv6->intf_id, &ifr6.ifr6_addr); - ifr6.ifr6_prefixlen = a->prefix_len; + build_addr(a, ses->ipv6->intf_id, &ifr6.ifr6_addr); + ifr6.ifr6_prefixlen = a->prefix_len; - if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6)) - log_ppp_error("failed to add IPv6 address: %s\n", strerror(errno)); + if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6)) + log_ppp_error("failed to add IPv6 address: %s\n", strerror(errno)); + } } - } - - if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr)) - log_ppp_error("failed to get interface flags: %s\n", strerror(errno)); - ifr.ifr_flags |= IFF_UP; + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr)) + log_ppp_error("failed to get interface flags: %s\n", strerror(errno)); - if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr)) - log_ppp_error("failed to set interface flags: %s\n", strerror(errno)); + ifr.ifr_flags |= IFF_UP; - if (ses->ctrl->type != CTRL_TYPE_IPOE) { - ppp = container_of(ses, typeof(*ppp), ses); - if (ses->ipv4) { - np.protocol = PPP_IP; - np.mode = NPMODE_PASS; + if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr)) + log_ppp_error("failed to set interface flags: %s\n", strerror(errno)); - if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np)) - log_ppp_error("failed to set NP (IPv4) mode: %s\n", strerror(errno)); - } - - if (ses->ipv6) { - np.protocol = PPP_IPV6; - np.mode = NPMODE_PASS; + if (ses->ctrl->type != CTRL_TYPE_IPOE) { + ppp = container_of(ses, typeof(*ppp), ses); + if (ses->ipv4) { + np.protocol = PPP_IP; + np.mode = NPMODE_PASS; + + if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np)) + log_ppp_error("failed to set NP (IPv4) mode: %s\n", strerror(errno)); + } + + if (ses->ipv6) { + np.protocol = PPP_IPV6; + np.mode = NPMODE_PASS; - if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np)) - log_ppp_error("failed to set NP (IPv6) mode: %s\n", strerror(errno)); + if (ioctl(ppp->unit_fd, PPPIOCSNPMODE, &np)) + log_ppp_error("failed to set NP (IPv6) mode: %s\n", strerror(errno)); + } } - } #ifdef USE_BACKUP - } + } #endif + } ses->ctrl->started(ses); @@ -182,6 +184,9 @@ void __export ap_session_ifdown(struct ap_session *ses) struct in6_ifreq ifr6; struct ipv6db_addr_t *a; + if (ses->ctrl->dont_ifcfg) + return; + memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, ses->ifname); diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h index ab6f699c..ac0704ba 100644 --- a/accel-pppd/include/ap_session.h +++ b/accel-pppd/include/ap_session.h @@ -42,6 +42,7 @@ struct ap_ctrl int mppe; char *calling_station_id; char *called_station_id; + int dont_ifcfg:1; void (*started)(struct ap_session*); void (*finished)(struct ap_session *); void (*terminate)(struct ap_session *, int hard); diff --git a/accel-pppd/libnetlink/iplink.c b/accel-pppd/libnetlink/iplink.c index df00285b..779a8aeb 100644 --- a/accel-pppd/libnetlink/iplink.c +++ b/accel-pppd/libnetlink/iplink.c @@ -11,6 +11,9 @@ #include <errno.h> #include <time.h> #include <sys/uio.h> +//#include <linux/if_link.h> +//#include <linux/if_addr.h> +//#include <linux/rtnetlink.h> #include "triton.h" #include "log.h" @@ -158,6 +161,141 @@ int __export iplink_get_stats(int ifindex, struct rtnl_link_stats *stats) return 0; } +int __export ipaddr_add(int ifindex, in_addr_t addr, int mask) +{ + struct ipaddr_req { + struct nlmsghdr n; + struct ifaddrmsg i; + char buf[1024]; + } req; + + if (!rth) + open_rth(); + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 1024); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; + req.n.nlmsg_type = RTM_NEWADDR; + req.i.ifa_family = AF_INET; + req.i.ifa_index = ifindex; + req.i.ifa_prefixlen = mask; + + addattr32(&req.n, sizeof(req), IFA_LOCAL, addr); + + if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) + return -1; + + return 0; +} + +int __export ipaddr_del(int ifindex, in_addr_t addr) +{ + struct ipaddr_req { + struct nlmsghdr n; + struct ifaddrmsg i; + char buf[1024]; + } req; + + if (!rth) + open_rth(); + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 1024); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_DELADDR; + req.i.ifa_family = AF_INET; + req.i.ifa_index = ifindex; + req.i.ifa_prefixlen = 32; + + addattr32(&req.n, sizeof(req), IFA_LOCAL, addr); + + if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) + return -1; + + return 0; +} + +int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst) +{ + struct ipaddr_req { + struct nlmsghdr n; + struct rtmsg i; + char buf[1024]; + } req; + + if (!rth) + open_rth(); + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 1024); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; + req.n.nlmsg_type = RTM_NEWROUTE; + req.i.rtm_family = AF_INET; + req.i.rtm_table = RT_TABLE_MAIN; + req.i.rtm_scope = RT_SCOPE_LINK; + req.i.rtm_protocol = RTPROT_BOOT; + req.i.rtm_type = RTN_UNICAST; + req.i.rtm_dst_len = 32; + + addattr32(&req.n, sizeof(req), RTA_PREFSRC, src); + addattr32(&req.n, sizeof(req), RTA_DST, dst); + addattr32(&req.n, sizeof(req), RTA_OIF, ifindex); + + if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) + return -1; + + return 0; +} + +int __export iproute_del(int ifindex, in_addr_t dst) +{ + struct ipaddr_req { + struct nlmsghdr n; + struct rtmsg i; + char buf[1024]; + } req; + + if (!rth) + open_rth(); + + if (!rth) + return -1; + + memset(&req, 0, sizeof(req) - 1024); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); + req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + req.n.nlmsg_type = RTM_DELROUTE; + req.i.rtm_family = AF_INET; + req.i.rtm_table = RT_TABLE_MAIN; + req.i.rtm_scope = RT_SCOPE_LINK; + req.i.rtm_protocol = RTPROT_BOOT; + req.i.rtm_type = RTN_UNICAST; + req.i.rtm_dst_len = 32; + + addattr32(&req.n, sizeof(req), RTA_DST, dst); + addattr32(&req.n, sizeof(req), RTA_OIF, ifindex); + + if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) + return -1; + + return 0; +} + + + static void init(void) { pthread_key_create(&rth_key, free_rth); diff --git a/accel-pppd/libnetlink/iplink.h b/accel-pppd/libnetlink/iplink.h index e67e8ed5..a6af6627 100644 --- a/accel-pppd/libnetlink/iplink.h +++ b/accel-pppd/libnetlink/iplink.h @@ -8,4 +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 ipaddr_add(int ifindex, in_addr_t addr, int mask); +int ipaddr_del(int ifindex, in_addr_t addr); + +int iproute_add(int ifindex, in_addr_t src, in_addr_t dst); +int iproute_del(int ifindex, in_addr_t dst); #endif diff --git a/drivers/ipoe/ipoe.c b/drivers/ipoe/ipoe.c index f2fbd828..c2c9b344 100644 --- a/drivers/ipoe/ipoe.c +++ b/drivers/ipoe/ipoe.c @@ -113,7 +113,7 @@ static int ipoe_do_nat(struct sk_buff *skb, __be32 new_addr, int to_peer); static void ipoe_queue_u(struct sk_buff *skb, __be32 addr); static int ipoe_lookup1_u(__be32 addr, unsigned long *ts); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) static const struct net_device_ops ipoe_netdev_ops; #endif @@ -554,7 +554,11 @@ static void ipoe_process_queue(struct work_struct *w) if (!ns) goto nl_err; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32) if (nla_put_u32(report_skb, IPOE_ATTR_IFINDEX, skb->dev ? skb->dev->ifindex : skb->skb_iif)) +#else + if (nla_put_u32(report_skb, IPOE_ATTR_IFINDEX, skb->dev ? skb->dev->ifindex : skb->iif)) +#endif goto nl_err; if (nla_put(report_skb, IPOE_ATTR_ETH_HDR, sizeof(*eth), eth)) @@ -703,8 +707,12 @@ static unsigned int ipt_in_hook(unsigned int hook, struct sk_buff *skb, const st } skb1->dev = ses->dev; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32) skb1->skb_iif = skb->dev->ifindex; - +#else + skb1->iif = skb->dev->ifindex; +#endif + cb_ptr = skb1->cb + sizeof(skb1->cb) - 2; *(__u16 *)cb_ptr = IPOE_MAGIC; @@ -843,7 +851,7 @@ static const struct header_ops ipoe_hard_header_ops = { static void ipoe_netdev_setup(struct net_device *dev) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) dev->hard_start_xmit = ipoe_xmit; #else dev->netdev_ops = &ipoe_netdev_ops; @@ -973,7 +981,7 @@ static int ipoe_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) genlmsg_end(msg, hdr); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) return genlmsg_unicast(msg, info->snd_pid); #else return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid); @@ -1044,7 +1052,7 @@ static int ipoe_nl_cmd_create(struct sk_buff *skb, struct genl_info *info) nla_put_u32(msg, IPOE_ATTR_IFINDEX, ret); genlmsg_end(msg, hdr); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) return genlmsg_unicast(msg, info->snd_pid); #else return genlmsg_unicast(genl_info_net(info), msg, info->snd_pid); @@ -1072,15 +1080,20 @@ static int ipoe_nl_cmd_delete(struct sk_buff *skb, struct genl_info *info) down(&ipoe_wlock); - rcu_read_lock(); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) - dev = dev_get_by_index_rcu(ifindex); + rtnl_lock(); + dev = __dev_get_by_index(&init_net, ifindex); #else + rcu_read_lock(); dev = dev_get_by_index_rcu(&init_net, ifindex); #endif if (!dev || dev->header_ops != &ipoe_hard_header_ops) r = 1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) + rtnl_unlock(); +#else rcu_read_unlock(); +#endif if (r) goto out_unlock; @@ -1129,15 +1142,20 @@ static int ipoe_nl_cmd_modify(struct sk_buff *skb, struct genl_info *info) ifindex = nla_get_u32(info->attrs[IPOE_ATTR_IFINDEX]); - rcu_read_lock(); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) - dev = dev_get_by_index_rcu(ifindex); + rtnl_lock(); + dev = __dev_get_by_index(&init_net, ifindex); #else + rcu_read_lock(); dev = dev_get_by_index_rcu(&init_net, ifindex); #endif if (!dev || dev->header_ops != &ipoe_hard_header_ops) r = 1; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) + rtnl_unlock(); +#else rcu_read_unlock(); +#endif if (r) goto out_unlock; @@ -1382,7 +1400,7 @@ static struct genl_multicast_group ipoe_nl_mcg = { .name = IPOE_GENL_MCG_PKT, }; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) static const struct net_device_ops ipoe_netdev_ops = { .ndo_start_xmit = ipoe_xmit, #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) |