X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fipv4%2Ffib_frontend.c;h=837f2957fa83d702a948dafb24b5cac1661a80ec;hb=cfd6c38096d75c8b86782683c5f45c415a505b78;hp=7f5217907e5aa84e8360a07c511c1e3c584c13f4;hpb=6d85c10abe840e98cbac673202fe7cc9ada2180c;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 7f52179..837f295 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -35,7 +34,6 @@ #include #include #include -#include #include #include @@ -47,6 +45,7 @@ #include #include #include +#include #define FFprint(a...) printk(KERN_DEBUG a) @@ -122,7 +121,7 @@ static void fib_flush(void) * Find the first device with a given source address. */ -struct net_device * ip_dev_find(u32 addr) +struct net_device * ip_dev_find(__be32 addr) { struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; @@ -146,7 +145,7 @@ out: return dev; } -unsigned inet_addr_type(u32 addr) +unsigned inet_addr_type(__be32 addr) { struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; struct fib_result res; @@ -160,7 +159,7 @@ unsigned inet_addr_type(u32 addr) #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; #endif - + if (ip_fib_local_table) { ret = RTN_UNICAST; if (!ip_fib_local_table->tb_lookup(ip_fib_local_table, @@ -253,7 +252,7 @@ e_inval: #ifndef CONFIG_IP_NOSIOCRT -static inline u32 sk_extract_addr(struct sockaddr *addr) +static inline __be32 sk_extract_addr(struct sockaddr *addr) { return ((struct sockaddr_in *) addr)->sin_addr.s_addr; } @@ -292,7 +291,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt, plen = 32; addr = sk_extract_addr(&rt->rt_dst); if (!(rt->rt_flags & RTF_HOST)) { - u32 mask = sk_extract_addr(&rt->rt_genmask); + __be32 mask = sk_extract_addr(&rt->rt_genmask); if (rt->rt_genmask.sa_family != AF_INET) { if (mask || rt->rt_genmask.sa_family) @@ -378,7 +377,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt, int len = 0; mx = kzalloc(3 * nla_total_size(4), GFP_KERNEL); - if (mx == NULL) + if (mx == NULL) return -ENOMEM; if (rt->rt_flags & RTF_MTU) @@ -400,7 +399,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt, /* * Handle IP routing ioctl calls. These are used to manipulate the routing tables */ - + int ip_rt_ioctl(unsigned int cmd, void __user *arg) { struct fib_config cfg; @@ -482,9 +481,7 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, memset(cfg, 0, sizeof(*cfg)); rtm = nlmsg_data(nlh); - cfg->fc_family = rtm->rtm_family; cfg->fc_dst_len = rtm->rtm_dst_len; - cfg->fc_src_len = rtm->rtm_src_len; cfg->fc_tos = rtm->rtm_tos; cfg->fc_table = rtm->rtm_table; cfg->fc_protocol = rtm->rtm_protocol; @@ -496,14 +493,16 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; cfg->fc_nlinfo.nlh = nlh; + if (cfg->fc_type > RTN_MAX) { + err = -EINVAL; + goto errout; + } + nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) { switch (attr->nla_type) { case RTA_DST: cfg->fc_dst = nla_get_be32(attr); break; - case RTA_SRC: - cfg->fc_src = nla_get_be32(attr); - break; case RTA_OIF: cfg->fc_oif = nla_get_u32(attr); break; @@ -541,7 +540,7 @@ errout: return err; } -int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) +static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { struct fib_config cfg; struct fib_table *tb; @@ -562,7 +561,7 @@ errout: return err; } -int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) +static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { struct fib_config cfg; struct fib_table *tb; @@ -583,7 +582,7 @@ errout: return err; } -int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) +static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) { unsigned int h, s_h; unsigned int e = 0, s_e; @@ -605,7 +604,7 @@ int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) goto next; if (dumped) memset(&cb->args[2], 0, sizeof(cb->args) - - 2 * sizeof(cb->args[0])); + 2 * sizeof(cb->args[0])); if (tb->tb_dump(tb, skb, cb) < 0) goto out; dumped = 1; @@ -627,8 +626,7 @@ out: only when netlink is already locked. */ -static void fib_magic(int cmd, int type, u32 dst, int dst_len, - struct in_ifaddr *ifa) +static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa) { struct fib_table *tb; struct fib_config cfg = { @@ -667,9 +665,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) struct in_device *in_dev = ifa->ifa_dev; struct net_device *dev = in_dev->dev; struct in_ifaddr *prim = ifa; - u32 mask = ifa->ifa_mask; - u32 addr = ifa->ifa_local; - u32 prefix = ifa->ifa_address&mask; + __be32 mask = ifa->ifa_mask; + __be32 addr = ifa->ifa_local; + __be32 prefix = ifa->ifa_address&mask; if (ifa->ifa_flags&IFA_F_SECONDARY) { prim = inet_ifa_byprefix(in_dev, prefix, mask); @@ -685,7 +683,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) return; /* Add broadcast address, if it is explicitly assigned. */ - if (ifa->ifa_broadcast && ifa->ifa_broadcast != 0xFFFFFFFF) + if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); if (!ZERONET(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) && @@ -707,8 +705,8 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) struct net_device *dev = in_dev->dev; struct in_ifaddr *ifa1; struct in_ifaddr *prim = ifa; - u32 brd = ifa->ifa_address|~ifa->ifa_mask; - u32 any = ifa->ifa_address&ifa->ifa_mask; + __be32 brd = ifa->ifa_address|~ifa->ifa_mask; + __be32 any = ifa->ifa_address&ifa->ifa_mask; #define LOCAL_OK 1 #define BRD_OK 2 #define BRD0_OK 4 @@ -772,12 +770,18 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) { - + struct fib_result res; - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr, - .fwmark = frn->fl_fwmark, + struct flowi fl = { .mark = frn->fl_mark, + .nl_u = { .ip4_u = { .daddr = frn->fl_addr, .tos = frn->fl_tos, .scope = frn->fl_scope } } }; + +#ifdef CONFIG_IP_MULTIPLE_TABLES + res.r = NULL; +#endif + + frn->err = -ENOENT; if (tb) { local_bh_disable(); @@ -789,6 +793,7 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) frn->nh_sel = res.nh_sel; frn->type = res.type; frn->scope = res.scope; + fib_res_put(&res); } local_bh_enable(); } @@ -797,34 +802,37 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) static void nl_fib_input(struct sock *sk, int len) { struct sk_buff *skb = NULL; - struct nlmsghdr *nlh = NULL; + struct nlmsghdr *nlh = NULL; struct fib_result_nl *frn; - u32 pid; + u32 pid; struct fib_table *tb; - + skb = skb_dequeue(&sk->sk_receive_queue); - nlh = (struct nlmsghdr *)skb->data; + if (skb == NULL) + return; + + nlh = nlmsg_hdr(skb); if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { kfree_skb(skb); return; } - + frn = (struct fib_result_nl *) NLMSG_DATA(nlh); tb = fib_get_table(frn->tb_id_in); nl_fib_lookup(frn, tb); - - pid = nlh->nlmsg_pid; /*pid of sending process */ + + pid = NETLINK_CB(skb).pid; /* pid of sending process */ NETLINK_CB(skb).pid = 0; /* from kernel */ - NETLINK_CB(skb).dst_pid = pid; NETLINK_CB(skb).dst_group = 0; /* unicast */ netlink_unicast(sk, skb, pid, MSG_DONTWAIT); -} +} static void nl_fib_lookup_init(void) { - netlink_kernel_create(NETLINK_FIB_LOOKUP, 0, nl_fib_input, THIS_MODULE); + netlink_kernel_create(NETLINK_FIB_LOOKUP, 0, nl_fib_input, NULL, + THIS_MODULE); } static void fib_disable_ip(struct net_device *dev, int force) @@ -922,6 +930,10 @@ void __init ip_fib_init(void) register_netdevice_notifier(&fib_netdev_notifier); register_inetaddr_notifier(&fib_inetaddr_notifier); nl_fib_lookup_init(); + + rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL); + rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL); + rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib); } EXPORT_SYMBOL(inet_addr_type);