diff --git a/include/net/route.h b/include/net/route.h index 8f5765ed46..24f37b7b4c 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -60,9 +60,11 @@ struct rtentry { - FAR struct sockaddr_storage *rt_target; /* Address of the network */ - FAR struct sockaddr_storage *rt_netmask; /* Network mask defining the sub-net */ - FAR struct sockaddr_storage *rt_router; /* Gateway address associated with the hop */ + struct sockaddr_storage rt_dst; /* Address of the network */ + struct sockaddr_storage rt_gateway; /* Gateway address associated with + * the hop */ + struct sockaddr_storage rt_genmask; /* Network mask defining the sub-net */ + uint16_t rt_flags; }; /**************************************************************************** diff --git a/include/netpacket/netlink.h b/include/netpacket/netlink.h index 67b4d416e5..a69e5a15e0 100644 --- a/include/netpacket/netlink.h +++ b/include/netpacket/netlink.h @@ -235,10 +235,14 @@ #define NLMSG_ALIGN(n) (((n) + NLMSG_MASK) & ~NLMSG_MASK) #define NLMSG_HDRLEN sizeof(struct nlmsghdr) #define NLMSG_LENGTH(n) (NLMSG_HDRLEN + (n)) +#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len)) #define NLMSG_DATA(hdr) ((FAR void*)(((FAR char*)hdr) + NLMSG_HDRLEN)) #define NLMSG_NEXT(hdr,n) \ ((n) -= NLMSG_ALIGN((hdr)->nlmsg_len), \ - (FAR struct nlmsghdr*)(((FAR cha r*)(hdr)) + NLMSG_ALIGN((hdr)->nlmsg_len))) + (FAR struct nlmsghdr*) \ + (((FAR cha r*)(hdr)) + NLMSG_ALIGN((hdr)->nlmsg_len))) +#define NLMSG_PAYLOAD(hdr, len) \ + ((hdr)->nlmsg_len - NLMSG_SPACE((len))) #define NLMSG_NOOP 1 /* Nothing */ #define NLMSG_ERROR 2 /* Error */ @@ -285,6 +289,58 @@ #define IFLA_IFNAME 1 +/* Definitions for struct rtmsg *********************************************/ + +#define RTM_RTA(r) ((FAR struct rtattr *)\ + (((FAR char *)(r)) + \ + NLMSG_ALIGN(sizeof(struct rtmsg)))) +#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct rtmsg)) + +/* rtm_table. Routing table identifiers */ + +#define RT_TABLE_UNSPEC 0 + /* 1-251: User defined values */ +#define RT_TABLE_MAIN 254 +#define RT_TABLE_MAX 0xffffffff + +/* rtm_type */ + +#define RTN_UNSPEC 0 +#define RTN_UNICAST 1 /* Gateway or direct route */ +#define RTN_LOCAL 2 /* Accept locally */ +#define RTN_BROADCAST 3 /* Accept locally as broadcast; + * send as broadcast */ +#define RTN_ANYCAST 4 /* Accept locally as broadcast + * but send as unicast */ +#define RTN_MULTICAST 5 /* Multicast route */ + +/* rtm_protocol */ + +#define RTPROT_UNSPEC 0 +#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects */ +#define RTPROT_KERNEL 2 /* Route installed by kernel */ +#define RTPROT_BOOT 3 /* Route installed during boot */ +#define RTPROT_STATIC 4 /* Route installed by administrator */ +#define RTPROT_RA 5 /* RDISC/ND router advertisements */ +#define RTPROT_DHCP 6 /* DHCP client */ + +/* rtm_scope */ + +#define RT_SCOPE_UNIVERSE 0 + /* 1-199: User defined values */ +#define RT_SCOPE_SITE 200 +#define RT_SCOPE_LINK 253 +#define RT_SCOPE_HOST 254 +#define RT_SCOPE_NOWHERE 255 + +/* Routing table attributes */ + +#define RTA_UNSPEC 0 +#define RTA_DST 1 +#define RTA_SRC 2 +#define RTA_GENMASK 3 +#define RTA_GATEWAY 5 + /**************************************************************************** * Public Type Definitions ****************************************************************************/ @@ -347,7 +403,7 @@ struct ifinfomsg struct rtgenmsg { - unsigned char rtgen_family; + uint8_t rtgen_family; }; /* RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR @@ -382,6 +438,21 @@ struct ndmsg uint8_t ndm_type; }; +/* Structures used in routing table administration. */ + +struct rtmsg +{ + uint8_t rtm_family; + uint8_t rtm_dst_len; + uint8_t rtm_src_len; + uint8_t rtm_tos; + uint8_t rtm_table; /* Routing table id */ + uint8_t rtm_protocol; /* Routing protocol; See RTPROT_ definitions. */ + uint8_t rtm_scope; /* See RT_SCOPE_* definitions */ + uint8_t rtm_type; /* See RTN_* definitions */ + uint32_t rtm_flags; +}; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/include/sys/socket.h b/include/sys/socket.h index 5cfe3e1812..b462cdaf8b 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -259,6 +259,8 @@ * aligned at an appropriate boundary so that pointers to it can be cast * as pointers to protocol-specific address structures and used to access * the fields of those structures without alignment problems. + * + * REVISIT: sizeof(struct sockaddr_storge) should be 128 bytes. */ #ifdef CONFIG_NET_IPv6 diff --git a/libs/libc/net/lib_addroute.c b/libs/libc/net/lib_addroute.c index 0f40a9e672..c72d438cc1 100644 --- a/libs/libc/net/lib_addroute.c +++ b/libs/libc/net/lib_addroute.c @@ -42,6 +42,7 @@ #include #include #include +#include #include /**************************************************************************** @@ -75,9 +76,10 @@ int addroute(int sockfd, FAR struct sockaddr_storage *target, /* Set up the rtentry structure */ - entry.rt_target = target; /* Target address */ - entry.rt_netmask = netmask; /* Network mask defining the sub-net */ - entry.rt_router = router; /* Router address associated with the hop */ + memset(&entry, 0, sizeof(struct rtentry)); + memcpy(&entry.rt_dst, target, sizeof(struct sockaddr_storage)); + memcpy(&entry.rt_genmask, netmask, sizeof(struct sockaddr_storage)); + memcpy(&entry.rt_gateway, router, sizeof(struct sockaddr_storage)); /* Then perform the ioctl */ diff --git a/libs/libc/net/lib_delroute.c b/libs/libc/net/lib_delroute.c index 689a1fc43e..ce3aa2e166 100644 --- a/libs/libc/net/lib_delroute.c +++ b/libs/libc/net/lib_delroute.c @@ -74,8 +74,8 @@ int delroute(int sockfd, FAR struct sockaddr_storage *target, /* Set up the rtentry structure */ memset(&entry, 0, sizeof(struct rtentry)); - entry.rt_target = target; /* Target address */ - entry.rt_netmask = netmask; /* Network mask defining the sub-net */ + memcpy(&entry.rt_dst, target, sizeof(struct sockaddr_storage)); + memcpy(&entry.rt_genmask, netmask, sizeof(struct sockaddr_storage)); /* Then perform the ioctl */ diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index b79e0fd5e0..dd740e01cb 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -168,23 +168,14 @@ static int ioctl_add_ipv4route(FAR struct rtentry *rtentry) in_addr_t netmask; in_addr_t router; - addr = (FAR struct sockaddr_in *)rtentry->rt_target; + addr = (FAR struct sockaddr_in *)&rtentry->rt_dst; target = (in_addr_t)addr->sin_addr.s_addr; - addr = (FAR struct sockaddr_in *)rtentry->rt_netmask; + addr = (FAR struct sockaddr_in *)&rtentry->rt_genmask; netmask = (in_addr_t)addr->sin_addr.s_addr; - /* The router is an optional argument */ - - if (rtentry->rt_router) - { - addr = (FAR struct sockaddr_in *)rtentry->rt_router; - router = (in_addr_t)addr->sin_addr.s_addr; - } - else - { - router = 0; - } + addr = (FAR struct sockaddr_in *)&rtentry->rt_gateway; + router = (in_addr_t)addr->sin_addr.s_addr; return net_addroute_ipv4(target, netmask, router); } @@ -206,23 +197,16 @@ static int ioctl_add_ipv6route(FAR struct rtentry *rtentry) { FAR struct sockaddr_in6 *target; FAR struct sockaddr_in6 *netmask; + FAR struct sockaddr_in6 *gateway; net_ipv6addr_t router; - target = (FAR struct sockaddr_in6 *)rtentry->rt_target; - netmask = (FAR struct sockaddr_in6 *)rtentry->rt_netmask; + target = (FAR struct sockaddr_in6 *)&rtentry->rt_dst; + netmask = (FAR struct sockaddr_in6 *)&rtentry->rt_genmask; /* The router is an optional argument */ - if (rtentry->rt_router) - { - FAR struct sockaddr_in6 *addr; - addr = (FAR struct sockaddr_in6 *)rtentry->rt_router; - net_ipv6addr_copy(router, addr->sin6_addr.s6_addr16); - } - else - { - net_ipv6addr_copy(router, in6addr_any.s6_addr16); - } + gateway = (FAR struct sockaddr_in6 *)&rtentry->rt_gateway; + net_ipv6addr_copy(router, gateway->sin6_addr.s6_addr16); return net_addroute_ipv6(target->sin6_addr.s6_addr16, netmask->sin6_addr.s6_addr16, router); @@ -247,10 +231,10 @@ static int ioctl_del_ipv4route(FAR struct rtentry *rtentry) in_addr_t target; in_addr_t netmask; - addr = (FAR struct sockaddr_in *)rtentry->rt_target; + addr = (FAR struct sockaddr_in *)&rtentry->rt_dst; target = (in_addr_t)addr->sin_addr.s_addr; - addr = (FAR struct sockaddr_in *)rtentry->rt_netmask; + addr = (FAR struct sockaddr_in *)&rtentry->rt_genmask; netmask = (in_addr_t)addr->sin_addr.s_addr; return net_delroute_ipv4(target, netmask); @@ -274,10 +258,11 @@ static int ioctl_del_ipv6route(FAR struct rtentry *rtentry) FAR struct sockaddr_in6 *target; FAR struct sockaddr_in6 *netmask; - target = (FAR struct sockaddr_in6 *)rtentry->rt_target; - netmask = (FAR struct sockaddr_in6 *)rtentry->rt_netmask; + target = (FAR struct sockaddr_in6 *)&rtentry->rt_dst; + netmask = (FAR struct sockaddr_in6 *)&rtentry->rt_genmask; - return net_delroute_ipv6(target->sin6_addr.s6_addr16, netmask->sin6_addr.s6_addr16); + return net_delroute_ipv6(target->sin6_addr.s6_addr16, + netmask->sin6_addr.s6_addr16); } #endif /* HAVE_WRITABLE_IPv6ROUTE */ @@ -1347,14 +1332,14 @@ static int netdev_rt_ioctl(FAR struct socket *psock, int cmd, { /* The target address and the netmask are required values */ - if (!rtentry || !rtentry->rt_target || !rtentry->rt_netmask) + if (rtentry == NULL) { return -EINVAL; } #ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv6 - if (rtentry->rt_target->ss_family == AF_INET) + if (rtentry->rt_dst.ss_family == AF_INET) #endif { #ifdef HAVE_WRITABLE_IPv4ROUTE @@ -1384,14 +1369,14 @@ static int netdev_rt_ioctl(FAR struct socket *psock, int cmd, { /* The target address and the netmask are required values */ - if (!rtentry || !rtentry->rt_target || !rtentry->rt_netmask) + if (rtentry == 0) { return -EINVAL; } #ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv6 - if (rtentry->rt_target->ss_family == AF_INET) + if (rtentry->rt_dst.ss_family == AF_INET) #endif { #ifdef HAVE_WRITABLE_IPv4ROUTE diff --git a/net/netlink/netlink_route.c b/net/netlink/netlink_route.c index 9f844cb874..d7013c7093 100644 --- a/net/netlink/netlink_route.c +++ b/net/netlink/netlink_route.c @@ -324,7 +324,7 @@ int netlink_device_callback(FAR struct net_driver_s *dev, FAR void *arg) resp->iface.ifi_flags = devcb->req->hdr.nlmsg_flags; resp->iface.ifi_change = 0xffffffff; - resp->attr.rta_len = strnlen(dev->d_ifname, IFNAMSIZ); + resp->attr.rta_len = RTA_LENGTH(0) + strnlen(dev->d_ifname, IFNAMSIZ); resp->attr.rta_type = IFLA_IFNAME; strncpy((FAR char *)resp->data, dev->d_ifname, IFNAMSIZ); @@ -390,7 +390,7 @@ int netlink_get_devlist(FAR struct socket *psock, resp->iface.ifi_flags = req->hdr.nlmsg_flags; resp->iface.ifi_change = 0xffffffff; - resp->attr.rta_len = 0; + resp->attr.rta_len = RTA_LENGTH(0); resp->attr.rta_type = NLMSG_DONE; /* Finally, add the data to the list of pending responses */ @@ -440,7 +440,7 @@ int netlink_get_arptable(FAR struct socket *psock, memcpy(&entry->payload.hdr, &req->hdr, sizeof(struct nlmsghdr)); entry->payload.hdr.nlmsg_len = rspsize; memcpy(&entry->payload.msg, &req->msg, sizeof(struct ndmsg)); - entry->payload.attr.rta_len = tabsize; + entry->payload.attr.rta_len = RTA_LENGTH(0) + tabsize; entry->payload.attr.rta_type = 0; /* Lock the network so that the ARP table will be stable, then copy @@ -473,7 +473,7 @@ int netlink_get_arptable(FAR struct socket *psock, } entry->payload.hdr.nlmsg_len = rspsize; - entry->payload.attr.rta_len = tabsize; + entry->payload.attr.rta_len = RTA_LENGTH(0) + tabsize; } /* Finally, add the data to the list of pending responses */ @@ -524,7 +524,7 @@ int netlink_get_nbtable(FAR struct socket *psock, memcpy(&entry->payload.hdr, &req->hdr, sizeof(struct nlmsghdr)); entry->payload.hdr.nlmsg_len = rspsize; memcpy(&entry->payload.msg, &req->msg, sizeof(struct ndmsg)); - entry->payload.attr.rta_len = tabsize; + entry->payload.attr.rta_len = RTA_LENGTH(0) + tabsize; entry->payload.attr.rta_type = 0; /* Lock the network so that the Neighbor table will be stable, then @@ -557,7 +557,7 @@ int netlink_get_nbtable(FAR struct socket *psock, } entry->payload.hdr.nlmsg_len = rspsize; - entry->payload.attr.rta_len = tabsize; + entry->payload.attr.rta_len = RTA_LENGTH(0) + tabsize; } /* Finally, add the data to the list of pending responses */