route.c (2d7202bfdd28687073f5efef8d2f51bbab0af867) | route.c (ab364a6f96bad9625bdb97b5688c76c44eb1e96e) |
---|---|
1/* 2 * Linux INET6 implementation 3 * FIB front-end. 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * $Id: route.c,v 1.56 2001/10/31 21:55:55 davem Exp $ --- 1819 unchanged lines hidden (view full) --- 1828 }; 1829 1830 fib6_clean_all(rt6_mtu_change_route, 0, &arg); 1831} 1832 1833static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { 1834 [RTA_GATEWAY] = { .minlen = sizeof(struct in6_addr) }, 1835 [RTA_OIF] = { .type = NLA_U32 }, | 1/* 2 * Linux INET6 implementation 3 * FIB front-end. 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * $Id: route.c,v 1.56 2001/10/31 21:55:55 davem Exp $ --- 1819 unchanged lines hidden (view full) --- 1828 }; 1829 1830 fib6_clean_all(rt6_mtu_change_route, 0, &arg); 1831} 1832 1833static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { 1834 [RTA_GATEWAY] = { .minlen = sizeof(struct in6_addr) }, 1835 [RTA_OIF] = { .type = NLA_U32 }, |
1836 [RTA_IIF] = { .type = NLA_U32 }, |
|
1836 [RTA_PRIORITY] = { .type = NLA_U32 }, 1837 [RTA_METRICS] = { .type = NLA_NESTED }, 1838}; 1839 1840static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, 1841 struct fib6_config *cfg) 1842{ 1843 struct rtmsg *rtm; --- 199 unchanged lines hidden (view full) --- 2043 2044 return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, 2045 NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, 2046 prefix, NLM_F_MULTI); 2047} 2048 2049int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) 2050{ | 1837 [RTA_PRIORITY] = { .type = NLA_U32 }, 1838 [RTA_METRICS] = { .type = NLA_NESTED }, 1839}; 1840 1841static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, 1842 struct fib6_config *cfg) 1843{ 1844 struct rtmsg *rtm; --- 199 unchanged lines hidden (view full) --- 2044 2045 return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, 2046 NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, 2047 prefix, NLM_F_MULTI); 2048} 2049 2050int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) 2051{ |
2051 struct rtattr **rta = arg; 2052 int iif = 0; 2053 int err = -ENOBUFS; | 2052 struct nlattr *tb[RTA_MAX+1]; 2053 struct rt6_info *rt; |
2054 struct sk_buff *skb; | 2054 struct sk_buff *skb; |
2055 struct rtmsg *rtm; |
|
2055 struct flowi fl; | 2056 struct flowi fl; |
2056 struct rt6_info *rt; | 2057 int err, iif = 0; |
2057 | 2058 |
2058 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 2059 if (skb == NULL) 2060 goto out; | 2059 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); 2060 if (err < 0) 2061 goto errout; |
2061 | 2062 |
2062 /* Reserve room for dummy headers, this skb can pass 2063 through good chunk of routing engine. 2064 */ 2065 skb->mac.raw = skb->data; 2066 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); 2067 | 2063 err = -EINVAL; |
2068 memset(&fl, 0, sizeof(fl)); | 2064 memset(&fl, 0, sizeof(fl)); |
2069 if (rta[RTA_SRC-1]) 2070 ipv6_addr_copy(&fl.fl6_src, 2071 (struct in6_addr*)RTA_DATA(rta[RTA_SRC-1])); 2072 if (rta[RTA_DST-1]) 2073 ipv6_addr_copy(&fl.fl6_dst, 2074 (struct in6_addr*)RTA_DATA(rta[RTA_DST-1])); | |
2075 | 2065 |
2076 if (rta[RTA_IIF-1]) 2077 memcpy(&iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int)); | 2066 if (tb[RTA_SRC]) { 2067 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr)) 2068 goto errout; |
2078 | 2069 |
2070 ipv6_addr_copy(&fl.fl6_src, nla_data(tb[RTA_SRC])); 2071 } 2072 2073 if (tb[RTA_DST]) { 2074 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr)) 2075 goto errout; 2076 2077 ipv6_addr_copy(&fl.fl6_dst, nla_data(tb[RTA_DST])); 2078 } 2079 2080 if (tb[RTA_IIF]) 2081 iif = nla_get_u32(tb[RTA_IIF]); 2082 2083 if (tb[RTA_OIF]) 2084 fl.oif = nla_get_u32(tb[RTA_OIF]); 2085 |
|
2079 if (iif) { 2080 struct net_device *dev; 2081 dev = __dev_get_by_index(iif); 2082 if (!dev) { 2083 err = -ENODEV; | 2086 if (iif) { 2087 struct net_device *dev; 2088 dev = __dev_get_by_index(iif); 2089 if (!dev) { 2090 err = -ENODEV; |
2084 goto out_free; | 2091 goto errout; |
2085 } 2086 } 2087 | 2092 } 2093 } 2094 |
2088 fl.oif = 0; 2089 if (rta[RTA_OIF-1]) 2090 memcpy(&fl.oif, RTA_DATA(rta[RTA_OIF-1]), sizeof(int)); | 2095 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 2096 if (skb == NULL) { 2097 err = -ENOBUFS; 2098 goto errout; 2099 } |
2091 | 2100 |
2092 rt = (struct rt6_info*)ip6_route_output(NULL, &fl); | 2101 /* Reserve room for dummy headers, this skb can pass 2102 through good chunk of routing engine. 2103 */ 2104 skb->mac.raw = skb->data; 2105 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); |
2093 | 2106 |
2107 rt = (struct rt6_info*) ip6_route_output(NULL, &fl); |
|
2094 skb->dst = &rt->u.dst; 2095 | 2108 skb->dst = &rt->u.dst; 2109 |
2096 NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; 2097 err = rt6_fill_node(skb, rt, 2098 &fl.fl6_dst, &fl.fl6_src, 2099 iif, | 2110 err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, |
2100 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2101 nlh->nlmsg_seq, 0, 0); 2102 if (err < 0) { | 2111 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2112 nlh->nlmsg_seq, 0, 0); 2113 if (err < 0) { |
2103 err = -EMSGSIZE; 2104 goto out_free; | 2114 kfree_skb(skb); 2115 goto errout; |
2105 } 2106 2107 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); | 2116 } 2117 2118 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); |
2108out: | 2119errout: |
2109 return err; | 2120 return err; |
2110out_free: 2111 kfree_skb(skb); 2112 goto out; | |
2113} 2114 2115void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) 2116{ 2117 struct sk_buff *skb; 2118 u32 pid = 0, seq = 0; 2119 struct nlmsghdr *nlh = NULL; 2120 int payload = sizeof(struct rtmsg) + 256; --- 298 unchanged lines hidden --- | 2121} 2122 2123void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) 2124{ 2125 struct sk_buff *skb; 2126 u32 pid = 0, seq = 0; 2127 struct nlmsghdr *nlh = NULL; 2128 int payload = sizeof(struct rtmsg) + 256; --- 298 unchanged lines hidden --- |