#include #include #include #include #include #include "dev.h" #include "str.h" #include "sock.h" #include "die.h" #include "link.h" int device_ifindex(const char *ifname) { int ret, sock, index; struct ifreq ifr; if (!strncmp("any", ifname, strlen("any"))) return 0; sock = af_socket(AF_INET); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ret = ioctl(sock, SIOCGIFINDEX, &ifr); if (!ret) index = ifr.ifr_ifindex; else index = -1; close(sock); return index; } static int __device_address6(const char *ifname, struct sockaddr_storage *ss) { int ret, family, found = -EINVAL; struct ifaddrs *ifaddr, *ifa; ret = getifaddrs(&ifaddr); if (ret < 0) panic("Cannot get device addresses for IPv6!\n"); for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { family = ifa->ifa_addr->sa_family; if (family != AF_INET6) continue; if (strcmp(ifa->ifa_name, ifname)) continue; memcpy(ss, ifa->ifa_addr, sizeof(*ss)); found = 0; break; } freeifaddrs(ifaddr); return found; } int device_address(const char *ifname, int af, struct sockaddr_storage *ss) { int ret, sock; struct ifreq ifr; if (!ss) return -EINVAL; if (!strncmp("any", ifname, strlen("any"))) return -EINVAL; if (af == AF_INET6) return __device_address6(ifname, ss); sock = af_socket(af); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ifr.ifr_addr.sa_family = af; ret = ioctl(sock, SIOCGIFADDR, &ifr); if (!ret) memcpy(ss, &ifr.ifr_addr, sizeof(ifr.ifr_addr)); close(sock); return ret; } int device_mtu(const char *ifname) { int ret, sock, mtu; struct ifreq ifr; sock = af_socket(AF_INET); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ret = ioctl(sock, SIOCGIFMTU, &ifr); if (!ret) mtu = ifr.ifr_mtu; else mtu = 0; close(sock); return mtu; } short device_get_flags(const char *ifname) { short flags; int ret, sock; struct ifreq ifr; sock = af_socket(AF_INET); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ret = ioctl(sock, SIOCGIFFLAGS, &ifr); if (!ret) flags = ifr.ifr_flags; else flags = 0; close(sock); return flags; } void device_set_flags(const char *ifname, const short flags) { int ret, sock; struct ifreq ifr; sock = af_socket(AF_INET); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ifr.ifr_flags = flags; ret = ioctl(sock, SIOCSIFFLAGS, &ifr); if (ret < 0) panic("Cannot set NIC flags!\n"); close(sock); } int device_up_and_running(char *ifname) { if (!ifname) return -EINVAL; if (!strncmp("any", ifname, strlen("any"))) return 1; return (device_get_flags(ifname) & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING); } u32 device_bitrate(const char *ifname) { u32 speed_c, speed_w; speed_c = ethtool_bitrate(ifname); speed_w = wireless_bitrate(ifname); return (speed_c == 0 ? speed_w : speed_c); } 46f4fa60dc0317'>root/net/sctp/transport.c
diff options
context:
space:
mode:
authorJulian Anastasov <ja@ssi.bg>2017-02-06 23:14:13 +0200
committerDavid S. Miller <davem@davemloft.net>2017-02-07 13:07:46 -0500
commitc86a773c78025f5b825bacd7b846f4fa60dc0317 (patch)
tree4ccbab5f25aafd2682341852882bb05d45174cbe /net/sctp/transport.c
parent4ff0620354f2b39b9fe2a91c22c4de9d1fba0c8e (diff)
sctp: add dst_pending_confirm flag
Add new transport flag to allow sockets to confirm neighbour. When same struct dst_entry can be used for many different neighbours we can not use it for pending confirmations. The flag is propagated from transport to every packet. It is reset when cached dst is reset. Reported-by: YueHaibing <yuehaibing@huawei.com> Fixes: 5110effee8fd ("net: Do delayed neigh confirmation.") Fixes: f2bb4bedf35d ("ipv4: Cache output routes in fib_info nexthops.") Signed-off-by: Julian Anastasov <ja@ssi.bg> Acked-by: Eric Dumazet <edumazet@google.com> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/transport.c')
-rw-r--r--net/sctp/transport.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/net/sctp/transport.c b/net/sctp/transport.c