int ipv6_route_ioctl(unsigned int cmd, void *arg) { struct in6_rtmsg rtmsg; int err; switch(cmd) { case SIOCADDRT: /* Add a route */ case SIOCDELRT: /* Delete a route */ if (!capable(CAP_NET_ADMIN)) return -EPERM; err = copy_from_user(&rtmsg, arg, sizeof(struct in6_rtmsg)); if (err) return -EFAULT; rtnl_lock(); switch (cmd) { case SIOCADDRT: err = ip6_route_add(&rtmsg, NULL); break; case SIOCDELRT: err = ip6_route_del(&rtmsg, NULL); break; default: err = -EINVAL; } rtnl_unlock(); return err; }; return -EINVAL; }
int ip6_fw_msg_add(struct ip6_fw_msg *msg) { struct in6_rtmsg rtmsg; struct ip6_fw_rule *rl; struct rt6_info *rt; int err; ipv6_addr_copy(&rtmsg.rtmsg_dst, &msg->dst); ipv6_addr_copy(&rtmsg.rtmsg_src, &msg->src); rtmsg.rtmsg_dst_len = msg->dst_len; rtmsg.rtmsg_src_len = msg->src_len; rtmsg.rtmsg_metric = IP6_RT_PRIO_FW; rl = ip6_fwrule_alloc(); if (rl == NULL) return -ENOMEM; rl->policy = msg->policy; rl->info.proto = msg->proto; rl->info.uli_u.data = msg->u.data; rtmsg.rtmsg_flags = RTF_NONEXTHOP|RTF_POLICY; err = ip6_route_add(&rtmsg); if (err) { ip6_fwrule_free(rl); return err; } /* The rest will not work for now. --ABK (989725) */ #ifndef notdef ip6_fwrule_free(rl); return -EPERM; #else rt->u.dst.error = -EPERM; if (msg->policy == IP6_FW_ACCEPT) { /* * Accept rules are never selected * (i.e. packets use normal forwarding) */ rt->u.dst.input = ip6_fw_discard; rt->u.dst.output = ip6_fw_discard; } else { rt->u.dst.input = ip6_fw_reject; rt->u.dst.output = ip6_fw_reject; } ip6_rule_add(rl); rt->rt6i_flowr = flow_clone((struct flow_rule *)rl); return 0; #endif }
static void addrconf_add_mroute(struct net_device *dev) { struct in6_rtmsg rtmsg; memset(&rtmsg, 0, sizeof(rtmsg)); ipv6_addr_set(&rtmsg.rtmsg_dst, __constant_htonl(0xFF000000), 0, 0, 0); rtmsg.rtmsg_dst_len = 8; rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF; rtmsg.rtmsg_ifindex = dev->ifindex; rtmsg.rtmsg_flags = RTF_UP|RTF_ADDRCONF; rtmsg.rtmsg_type = RTMSG_NEWROUTE; ip6_route_add(&rtmsg); }
struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr, struct net_device *dev) { struct in6_rtmsg rtmsg; memset(&rtmsg, 0, sizeof(struct in6_rtmsg)); rtmsg.rtmsg_type = RTMSG_NEWROUTE; ipv6_addr_copy(&rtmsg.rtmsg_gateway, gwaddr); rtmsg.rtmsg_metric = 1024; rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP; rtmsg.rtmsg_ifindex = dev->ifindex; ip6_route_add(&rtmsg, NULL); return rt6_get_dflt_router(gwaddr, dev); }
static void sit_route_add(struct net_device *dev) { struct in6_rtmsg rtmsg; memset(&rtmsg, 0, sizeof(rtmsg)); rtmsg.rtmsg_type = RTMSG_NEWROUTE; rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF; /* prefix length - 96 bytes "::d.d.d.d" */ rtmsg.rtmsg_dst_len = 96; rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP; rtmsg.rtmsg_ifindex = dev->ifindex; ip6_route_add(&rtmsg); }
static void addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, unsigned long expires, unsigned flags) { struct in6_rtmsg rtmsg; memset(&rtmsg, 0, sizeof(rtmsg)); memcpy(&rtmsg.rtmsg_dst, pfx, sizeof(struct in6_addr)); rtmsg.rtmsg_dst_len = plen; rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF; rtmsg.rtmsg_ifindex = dev->ifindex; rtmsg.rtmsg_info = expires; rtmsg.rtmsg_flags = RTF_UP|flags; rtmsg.rtmsg_type = RTMSG_NEWROUTE; /* Prevent useless cloning on PtP SIT. This thing is done here expecting that the whole class of non-broadcast devices need not cloning. */ if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT)) rtmsg.rtmsg_flags |= RTF_NONEXTHOP; ip6_route_add(&rtmsg); }