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 ---