转:http://blog.csdn.net/nerdx/article/details/12841467
-
-
-
1.1 static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
-
[4] = { .doit = inet_rtm_newaddr, },
-
[5] = { .doit = inet_rtm_deladdr, },
-
[6] = { .dumpit = inet_dump_ifaddr, },
-
[8] = { .doit = inet_rtm_newroute, },
-
[9] = { .doit = inet_rtm_delroute, },
-
[10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, },
-
#ifdef CONFIG_IP_MULTIPLE_TABLES
-
[16] = { .doit = inet_rtm_newrule, },
-
[17] = { .doit = inet_rtm_delrule, },
-
[18] = { .dumpit = inet_dump_rules, },
-
#endif
-
};
-
-
-
-
-
-
-
-
-
1.2 static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
-
{
-
struct rtattr **rta = arg;
-
struct net_device *dev;
-
struct in_device *in_dev;
-
struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
-
struct in_ifaddr *ifa;
-
int rc = -EINVAL;
-
-
-
if (ifm->ifa_prefixlen > 32 || !rta[IFA_LOCAL - 1])
-
goto out;
-
-
rc = -ENODEV;
-
-
if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL)
-
goto out;
-
-
rc = -ENOBUFS;
-
-
if ((in_dev = __in_dev_get(dev)) == NULL) {
-
-
in_dev = inetdev_init(dev);
-
}
-
-
if ((ifa = inet_alloc_ifa()) == NULL)
-
goto out;
-
-
-
-
-
if (!rta[IFA_ADDRESS - 1])
-
rta[IFA_ADDRESS - 1] = rta[IFA_LOCAL - 1];
-
memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL - 1]), 4);
-
memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS - 1]), 4);
-
-
ifa->ifa_prefixlen = ifm->ifa_prefixlen;
-
-
ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
-
-
if (rta[IFA_BROADCAST - 1])
-
memcpy(&ifa->ifa_broadcast,
-
RTA_DATA(rta[IFA_BROADCAST - 1]), 4);
-
-
if (rta[IFA_ANYCAST - 1])
-
memcpy(&ifa->ifa_anycast, RTA_DATA(rta[IFA_ANYCAST - 1]), 4);
-
-
ifa->ifa_flags = ifm->ifa_flags;
-
ifa->ifa_scope = ifm->ifa_scope;
-
in_dev_hold(in_dev);
-
ifa->ifa_dev = in_dev;
-
-
if (rta[IFA_LABEL - 1])
-
rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL - 1], IFNAMSIZ);
-
else
-
memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
-
-
rc = inet_insert_ifa(ifa);
-
out:
-
return rc;
-
}
-
-
-
-
-
-
1.3 static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
-
{
-
struct rtattr **rta = arg;
-
struct in_device *in_dev;
-
struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
-
struct in_ifaddr *ifa, **ifap;
-
-
if ((in_dev = inetdev_by_index(ifm->ifa_index)) == NULL)
-
goto out;
-
__in_dev_put(in_dev);
-
-
for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
-
ifap = &ifa->ifa_next) {
-
if ((rta[IFA_LOCAL - 1] &&
-
memcmp(RTA_DATA(rta[IFA_LOCAL - 1]),
-
&ifa->ifa_local, 4)) ||
-
(rta[IFA_LABEL - 1] &&
-
rtattr_strcmp(rta[IFA_LABEL - 1], ifa->ifa_label)) ||
-
(rta[IFA_ADDRESS - 1] &&
-
(ifm->ifa_prefixlen != ifa->ifa_prefixlen ||
-
!inet_ifa_match(*(u32*)RTA_DATA(rta[IFA_ADDRESS - 1]),
-
ifa))))
-
continue;
-
-
inet_del_ifa(in_dev, ifap, 1);
-
return 0;
-
}
-
out:
-
return -EADDRNOTAVAIL;
-
}
-
-
-
-
1.4 int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
-
{
-
struct fib_table * tb;
-
struct rtattr **rta = arg;
-
struct rtmsg *r = NLMSG_DATA(nlh);
-
-
if (inet_check_attr(r, rta))
-
return -EINVAL;
-
-
tb = fib_new_table(r->rtm_table);
-
if (tb)
-
return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb));
-
return -ENOBUFS;
-
}
-
-
-
-
-
-
-
1.5 int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
-
{
-
struct rtattr **rta = arg;
-
struct rtmsg *rtm = NLMSG_DATA(nlh);
-
struct rtable *rt = NULL;
-
u32 dst = 0;
-
u32 src = 0;
-
int iif = 0;
-
int err = -ENOBUFS;
-
struct sk_buff *skb;
-
-
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
-
if (!skb)
-
goto out;
-
-
skb->mac.raw = skb->data;
-
skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr));
-
-
if (rta[RTA_SRC - 1])
-
memcpy(&src, RTA_DATA(rta[RTA_SRC - 1]), 4);
-
if (rta[RTA_DST - 1])
-
memcpy(&dst, RTA_DATA(rta[RTA_DST - 1]), 4);
-
if (rta[RTA_IIF - 1])
-
memcpy(&iif, RTA_DATA(rta[RTA_IIF - 1]), sizeof(int));
-
-
if (iif) {
-
struct net_device *dev = __dev_get_by_index(iif);
-
err = -ENODEV;
-
if (!dev)
-
goto out_free;
-
skb->protocol = htons(ETH_P_IP);
-
skb->dev = dev;
-
local_bh_disable();
-
-
err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
-
local_bh_enable();
-
rt = (struct rtable*)skb->dst;
-
if (!err && rt->u.dst.error)
-
err = -rt->u.dst.error;
-
-
} else {
-
-
struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dst,
-
.saddr = src,
-
.tos = rtm->rtm_tos } } };
-
int oif = 0;
-
-
if (rta[RTA_OIF - 1])
-
memcpy(&oif, RTA_DATA(rta[RTA_OIF - 1]), sizeof(int));
-
fl.oif = oif;
-
-
err = ip_route_output_key(&rt, &fl);
-
}
-
if (err)
-
goto out_free;
-
-
skb->dst = &rt->u.dst;
-
if (rtm->rtm_flags & RTM_F_NOTIFY)
-
rt->rt_flags |= RTCF_NOTIFY;
-
-
NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
-
-
err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
-
RTM_NEWROUTE, 0);
-
-
err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
-
if (err > 0)
-
err = 0;
-
out: return err;
-
-
out_free:
-
kfree_skb(skb);
-
goto out;
-
}
-
阅读(1106) | 评论(0) | 转发(0) |