Loading net/ipv6/addrconf.c +45 −27 Original line number Original line Diff line number Diff line Loading @@ -2868,6 +2868,29 @@ static void addrconf_verify(unsigned long foo) spin_unlock_bh(&addrconf_verify_lock); spin_unlock_bh(&addrconf_verify_lock); } } static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) { struct in6_addr *pfx = NULL; if (addr) pfx = nla_data(addr); if (local) { if (pfx && nla_memcmp(local, pfx, sizeof(*pfx))) pfx = NULL; else pfx = nla_data(local); } return pfx; } static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, }; static int static int inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { { Loading Loading @@ -2945,46 +2968,41 @@ inet6_addr_modify(int ifindex, struct in6_addr *pfx, static int static int inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { { struct rtattr **rta = arg; struct ifaddrmsg *ifm; struct ifaddrmsg *ifm = NLMSG_DATA(nlh); struct nlattr *tb[IFA_MAX+1]; struct in6_addr *pfx; struct in6_addr *pfx; __u32 valid_lft = INFINITY_LIFE_TIME, prefered_lft = INFINITY_LIFE_TIME; u32 valid_lft, preferred_lft; int err; pfx = NULL; err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); if (rta[IFA_ADDRESS-1]) { if (err < 0) if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*pfx)) return err; return -EINVAL; pfx = RTA_DATA(rta[IFA_ADDRESS-1]); ifm = nlmsg_data(nlh); } pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); if (rta[IFA_LOCAL-1]) { if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) || (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))) return -EINVAL; pfx = RTA_DATA(rta[IFA_LOCAL-1]); } if (pfx == NULL) if (pfx == NULL) return -EINVAL; return -EINVAL; if (rta[IFA_CACHEINFO-1]) { if (tb[IFA_CACHEINFO]) { struct ifa_cacheinfo *ci; struct ifa_cacheinfo *ci; if (RTA_PAYLOAD(rta[IFA_CACHEINFO-1]) < sizeof(*ci)) return -EINVAL; ci = nla_data(tb[IFA_CACHEINFO]); ci = RTA_DATA(rta[IFA_CACHEINFO-1]); valid_lft = ci->ifa_valid; valid_lft = ci->ifa_valid; prefered_lft = ci->ifa_prefered; preferred_lft = ci->ifa_prefered; } else { preferred_lft = INFINITY_LIFE_TIME; valid_lft = INFINITY_LIFE_TIME; } } if (nlh->nlmsg_flags & NLM_F_REPLACE) { if (nlh->nlmsg_flags & NLM_F_REPLACE) { int ret; err = inet6_addr_modify(ifm->ifa_index, pfx, ret = inet6_addr_modify(ifm->ifa_index, pfx, preferred_lft, valid_lft); prefered_lft, valid_lft); if (err == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE)) if (ret == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE)) return err; return ret; } } return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, prefered_lft, valid_lft); preferred_lft, valid_lft); } } /* Maximum length of ifa_cacheinfo attributes */ /* Maximum length of ifa_cacheinfo attributes */ Loading Loading
net/ipv6/addrconf.c +45 −27 Original line number Original line Diff line number Diff line Loading @@ -2868,6 +2868,29 @@ static void addrconf_verify(unsigned long foo) spin_unlock_bh(&addrconf_verify_lock); spin_unlock_bh(&addrconf_verify_lock); } } static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) { struct in6_addr *pfx = NULL; if (addr) pfx = nla_data(addr); if (local) { if (pfx && nla_memcmp(local, pfx, sizeof(*pfx))) pfx = NULL; else pfx = nla_data(local); } return pfx; } static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, }; static int static int inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { { Loading Loading @@ -2945,46 +2968,41 @@ inet6_addr_modify(int ifindex, struct in6_addr *pfx, static int static int inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { { struct rtattr **rta = arg; struct ifaddrmsg *ifm; struct ifaddrmsg *ifm = NLMSG_DATA(nlh); struct nlattr *tb[IFA_MAX+1]; struct in6_addr *pfx; struct in6_addr *pfx; __u32 valid_lft = INFINITY_LIFE_TIME, prefered_lft = INFINITY_LIFE_TIME; u32 valid_lft, preferred_lft; int err; pfx = NULL; err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); if (rta[IFA_ADDRESS-1]) { if (err < 0) if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*pfx)) return err; return -EINVAL; pfx = RTA_DATA(rta[IFA_ADDRESS-1]); ifm = nlmsg_data(nlh); } pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); if (rta[IFA_LOCAL-1]) { if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) || (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))) return -EINVAL; pfx = RTA_DATA(rta[IFA_LOCAL-1]); } if (pfx == NULL) if (pfx == NULL) return -EINVAL; return -EINVAL; if (rta[IFA_CACHEINFO-1]) { if (tb[IFA_CACHEINFO]) { struct ifa_cacheinfo *ci; struct ifa_cacheinfo *ci; if (RTA_PAYLOAD(rta[IFA_CACHEINFO-1]) < sizeof(*ci)) return -EINVAL; ci = nla_data(tb[IFA_CACHEINFO]); ci = RTA_DATA(rta[IFA_CACHEINFO-1]); valid_lft = ci->ifa_valid; valid_lft = ci->ifa_valid; prefered_lft = ci->ifa_prefered; preferred_lft = ci->ifa_prefered; } else { preferred_lft = INFINITY_LIFE_TIME; valid_lft = INFINITY_LIFE_TIME; } } if (nlh->nlmsg_flags & NLM_F_REPLACE) { if (nlh->nlmsg_flags & NLM_F_REPLACE) { int ret; err = inet6_addr_modify(ifm->ifa_index, pfx, ret = inet6_addr_modify(ifm->ifa_index, pfx, preferred_lft, valid_lft); prefered_lft, valid_lft); if (err == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE)) if (ret == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE)) return err; return ret; } } return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, prefered_lft, valid_lft); preferred_lft, valid_lft); } } /* Maximum length of ifa_cacheinfo attributes */ /* Maximum length of ifa_cacheinfo attributes */ Loading