From 8007bfb5adc596030a92607c9c2ef9dc053cf39f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 10 Nov 2009 08:51:17 -0800 Subject: [PATCH 01/59] Update to 2.6.32 kernel headers --- include/linux/if_addr.h | 1 + include/linux/if_arp.h | 1 - include/linux/if_tunnel.h | 2 +- include/linux/netdevice.h | 5 - include/linux/rtnetlink.h | 2 +- include/linux/socket.h | 287 -------------------------------------- 6 files changed, 3 insertions(+), 295 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index 08ea9800..41b0193d 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -41,6 +41,7 @@ enum #define IFA_F_NODAD 0x02 #define IFA_F_OPTIMISTIC 0x04 +#define IFA_F_DADFAILED 0x08 #define IFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE 0x40 diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index f1869439..57a8f38e 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -87,7 +87,6 @@ #define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */ #define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */ #define ARPHRD_IEEE802154 804 -#define ARPHRD_IEEE802154_PHY 805 #define ARPHRD_PHONET 820 /* PhoNet media type */ #define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */ diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 92290759..3036cec1 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h @@ -41,7 +41,7 @@ struct ip_tunnel_prl { __u16 flags; __u16 __reserved; __u32 datalen; - __u32 rs_delay; + __u32 __reserved2; /* data follows */ }; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 2faed2a9..260f0109 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -32,11 +32,6 @@ #define MAX_ADDR_LEN 32 /* Largest hardware address length */ -/* Driver transmit return codes */ -#define NETDEV_TX_OK 0 /* driver took care of packet */ -#define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ -#define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ - /* * Network device statistics. Akin to the 2.0 ether stats but diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 63d1c697..e8623807 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -104,7 +104,7 @@ enum { RTM_NEWADDRLABEL = 72, #define RTM_NEWADDRLABEL RTM_NEWADDRLABEL RTM_DELADDRLABEL, -#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL +#define RTM_DELADDRLABEL RTM_DELADDRLABEL RTM_GETADDRLABEL, #define RTM_GETADDRLABEL RTM_GETADDRLABEL diff --git a/include/linux/socket.h b/include/linux/socket.h index dff22f98..1057869e 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -16,291 +16,4 @@ struct __kernel_sockaddr_storage { /* _SS_MAXSIZE value minus size of ss_family */ } __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */ -#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) - -#include /* arch-dependent defines */ -#include /* the SIOCxxx I/O controls */ -#include /* iovec support */ -#include /* pid_t */ - /* */ - - -typedef unsigned short sa_family_t; - -/* - * 1003.1g requires sa_family_t and that sa_data is char. - */ - -struct sockaddr { - sa_family_t sa_family; /* address family, AF_xxx */ - char sa_data[14]; /* 14 bytes of protocol address */ -}; - -struct linger { - int l_onoff; /* Linger active */ - int l_linger; /* How long to linger for */ -}; - -#define sockaddr_storage __kernel_sockaddr_storage - -/* - * As we do 4.4BSD message passing we use a 4.4BSD message passing - * system, not 4.3. Thus msg_accrights(len) are now missing. They - * belong in an obscure libc emulation or the bin. - */ - -struct msghdr { - void * msg_name; /* Socket name */ - int msg_namelen; /* Length of name */ - struct iovec * msg_iov; /* Data blocks */ - __kernel_size_t msg_iovlen; /* Number of blocks */ - void * msg_control; /* Per protocol magic (eg BSD file descriptor passing) */ - __kernel_size_t msg_controllen; /* Length of cmsg list */ - unsigned msg_flags; -}; - -/* - * POSIX 1003.1g - ancillary data object information - * Ancillary data consits of a sequence of pairs of - * (cmsghdr, cmsg_data[]) - */ - -struct cmsghdr { - __kernel_size_t cmsg_len; /* data byte count, including hdr */ - int cmsg_level; /* originating protocol */ - int cmsg_type; /* protocol-specific type */ -}; - -/* - * Ancilliary data object information MACROS - * Table 5-14 of POSIX 1003.1g - */ - -#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg)) -#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg)) - -#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) ) - -#define CMSG_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr)))) -#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len)) -#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) - -#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? \ - (struct cmsghdr *)(ctl) : \ - (struct cmsghdr *)NULL) -#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen) -#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \ - (cmsg)->cmsg_len <= (unsigned long) \ - ((mhdr)->msg_controllen - \ - ((char *)(cmsg) - (char *)(mhdr)->msg_control))) - -/* - * This mess will go away with glibc - */ - -#if defined(__GNUC__) -#define __KINLINE static __inline__ -#elif defined(__cplusplus) -#define __KINLINE static __inline__ -#else -#define __KINLINE static -#endif - - -/* - * Get the next cmsg header - * - * PLEASE, do not touch this function. If you think, that it is - * incorrect, grep kernel sources and think about consequences - * before trying to improve it. - * - * Now it always returns valid, not truncated ancillary object - * HEADER. But caller still MUST check, that cmsg->cmsg_len is - * inside range, given by msg->msg_controllen before using - * ancillary object DATA. --ANK (980731) - */ - -__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size, - struct cmsghdr *__cmsg) -{ - struct cmsghdr * __ptr; - - __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len)); - if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size) - return (struct cmsghdr *)0; - - return __ptr; -} - -__KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg) -{ - return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg); -} - -/* "Socket"-level control message types: */ - -#define SCM_RIGHTS 0x01 /* rw: access rights (array of int) */ -#define SCM_CREDENTIALS 0x02 /* rw: struct ucred */ -#define SCM_SECURITY 0x03 /* rw: security label */ - -struct ucred { - __u32 pid; - __u32 uid; - __u32 gid; -}; - -/* Supported address families. */ -#define AF_UNSPEC 0 -#define AF_UNIX 1 /* Unix domain sockets */ -#define AF_LOCAL 1 /* POSIX name for AF_UNIX */ -#define AF_INET 2 /* Internet IP Protocol */ -#define AF_AX25 3 /* Amateur Radio AX.25 */ -#define AF_IPX 4 /* Novell IPX */ -#define AF_APPLETALK 5 /* AppleTalk DDP */ -#define AF_NETROM 6 /* Amateur Radio NET/ROM */ -#define AF_BRIDGE 7 /* Multiprotocol bridge */ -#define AF_ATMPVC 8 /* ATM PVCs */ -#define AF_X25 9 /* Reserved for X.25 project */ -#define AF_INET6 10 /* IP version 6 */ -#define AF_ROSE 11 /* Amateur Radio X.25 PLP */ -#define AF_DECnet 12 /* Reserved for DECnet project */ -#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/ -#define AF_SECURITY 14 /* Security callback pseudo AF */ -#define AF_KEY 15 /* PF_KEY key management API */ -#define AF_NETLINK 16 -#define AF_ROUTE AF_NETLINK /* Alias to emulate 4.4BSD */ -#define AF_PACKET 17 /* Packet family */ -#define AF_ASH 18 /* Ash */ -#define AF_ECONET 19 /* Acorn Econet */ -#define AF_ATMSVC 20 /* ATM SVCs */ -#define AF_RDS 21 /* RDS sockets */ -#define AF_SNA 22 /* Linux SNA Project (nutters!) */ -#define AF_IRDA 23 /* IRDA sockets */ -#define AF_PPPOX 24 /* PPPoX sockets */ -#define AF_WANPIPE 25 /* Wanpipe API Sockets */ -#define AF_LLC 26 /* Linux LLC */ -#define AF_CAN 29 /* Controller Area Network */ -#define AF_TIPC 30 /* TIPC sockets */ -#define AF_BLUETOOTH 31 /* Bluetooth sockets */ -#define AF_IUCV 32 /* IUCV sockets */ -#define AF_RXRPC 33 /* RxRPC sockets */ -#define AF_ISDN 34 /* mISDN sockets */ -#define AF_PHONET 35 /* Phonet sockets */ -#define AF_IEEE802154 36 /* IEEE802154 sockets */ -#define AF_MAX 37 /* For now.. */ - -/* Protocol families, same as address families. */ -#define PF_UNSPEC AF_UNSPEC -#define PF_UNIX AF_UNIX -#define PF_LOCAL AF_LOCAL -#define PF_INET AF_INET -#define PF_AX25 AF_AX25 -#define PF_IPX AF_IPX -#define PF_APPLETALK AF_APPLETALK -#define PF_NETROM AF_NETROM -#define PF_BRIDGE AF_BRIDGE -#define PF_ATMPVC AF_ATMPVC -#define PF_X25 AF_X25 -#define PF_INET6 AF_INET6 -#define PF_ROSE AF_ROSE -#define PF_DECnet AF_DECnet -#define PF_NETBEUI AF_NETBEUI -#define PF_SECURITY AF_SECURITY -#define PF_KEY AF_KEY -#define PF_NETLINK AF_NETLINK -#define PF_ROUTE AF_ROUTE -#define PF_PACKET AF_PACKET -#define PF_ASH AF_ASH -#define PF_ECONET AF_ECONET -#define PF_ATMSVC AF_ATMSVC -#define PF_RDS AF_RDS -#define PF_SNA AF_SNA -#define PF_IRDA AF_IRDA -#define PF_PPPOX AF_PPPOX -#define PF_WANPIPE AF_WANPIPE -#define PF_LLC AF_LLC -#define PF_CAN AF_CAN -#define PF_TIPC AF_TIPC -#define PF_BLUETOOTH AF_BLUETOOTH -#define PF_IUCV AF_IUCV -#define PF_RXRPC AF_RXRPC -#define PF_ISDN AF_ISDN -#define PF_PHONET AF_PHONET -#define PF_IEEE802154 AF_IEEE802154 -#define PF_MAX AF_MAX - -/* Maximum queue length specifiable by listen. */ -#define SOMAXCONN 128 - -/* Flags we can use with send/ and recv. - Added those for 1003.1g not all are supported yet - */ - -#define MSG_OOB 1 -#define MSG_PEEK 2 -#define MSG_DONTROUTE 4 -#define MSG_TRYHARD 4 /* Synonym for MSG_DONTROUTE for DECnet */ -#define MSG_CTRUNC 8 -#define MSG_PROBE 0x10 /* Do not send. Only probe path f.e. for MTU */ -#define MSG_TRUNC 0x20 -#define MSG_DONTWAIT 0x40 /* Nonblocking io */ -#define MSG_EOR 0x80 /* End of record */ -#define MSG_WAITALL 0x100 /* Wait for a full request */ -#define MSG_FIN 0x200 -#define MSG_SYN 0x400 -#define MSG_CONFIRM 0x800 /* Confirm path validity */ -#define MSG_RST 0x1000 -#define MSG_ERRQUEUE 0x2000 /* Fetch message from error queue */ -#define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */ -#define MSG_MORE 0x8000 /* Sender will send more */ - -#define MSG_EOF MSG_FIN - -#define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exit for file - descriptor received through - SCM_RIGHTS */ -#if defined(CONFIG_COMPAT) -#define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */ -#else -#define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */ -#endif - - -/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ -#define SOL_IP 0 -/* #define SOL_ICMP 1 No-no-no! Due to Linux :-) we cannot use SOL_ICMP=1 */ -#define SOL_TCP 6 -#define SOL_UDP 17 -#define SOL_IPV6 41 -#define SOL_ICMPV6 58 -#define SOL_SCTP 132 -#define SOL_UDPLITE 136 /* UDP-Lite (RFC 3828) */ -#define SOL_RAW 255 -#define SOL_IPX 256 -#define SOL_AX25 257 -#define SOL_ATALK 258 -#define SOL_NETROM 259 -#define SOL_ROSE 260 -#define SOL_DECNET 261 -#define SOL_X25 262 -#define SOL_PACKET 263 -#define SOL_ATM 264 /* ATM layer (cell level) */ -#define SOL_AAL 265 /* ATM Adaption Layer (packet level) */ -#define SOL_IRDA 266 -#define SOL_NETBEUI 267 -#define SOL_LLC 268 -#define SOL_DCCP 269 -#define SOL_NETLINK 270 -#define SOL_TIPC 271 -#define SOL_RXRPC 272 -#define SOL_PPPOL2TP 273 -#define SOL_BLUETOOTH 274 -#define SOL_PNPIPE 275 -#define SOL_RDS 276 -#define SOL_IUCV 277 - -/* IPX options */ -#define IPX_TYPE 1 - -#endif /* not kernel and not glibc */ #endif /* _LINUX_SOCKET_H */ From 8a1c7fcb2756be05b55008edbd9e813f590cdf01 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 10 Nov 2009 09:01:57 -0800 Subject: [PATCH 02/59] Consolidate fprintf statements Doing one item per call is like old MODULA2 code. --- ip/ipxfrm.c | 78 +++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 51 deletions(-) diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index 708ce9fe..18250de8 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -351,16 +351,12 @@ void xfrm_stats_print(struct xfrm_stats *s, FILE *fp, const char *prefix) { if (prefix) fputs(prefix, fp); - fprintf(fp, "stats:"); - fprintf(fp, "%s", _SL_); + fprintf(fp, "stats:%s", _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "replay-window %u ", s->replay_window); - fprintf(fp, "replay %u ", s->replay); - fprintf(fp, "failed %u", s->integrity_failed); - fprintf(fp, "%s", _SL_); + fprintf(fp, " replay-window %u replay %u failed %u%s", + s->replay_window, s->replay, s->integrity_failed, _SL_); } static const char *strxf_time(__u64 time) @@ -392,72 +388,52 @@ void xfrm_lifetime_print(struct xfrm_lifetime_cfg *cfg, if (cfg) { if (prefix) fputs(prefix, fp); - fprintf(fp, "lifetime config:"); - fprintf(fp, "%s", _SL_); + fprintf(fp, "lifetime config:%s",_SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "limit: "); - fprintf(fp, "soft "); - fprintf(fp, strxf_limit(cfg->soft_byte_limit)); - fprintf(fp, "(bytes), hard "); - fprintf(fp, strxf_limit(cfg->hard_byte_limit)); - fprintf(fp, "(bytes)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " limit: soft %s(bytes),", + strxf_limit(cfg->soft_byte_limit)); + fprintf(fp, " hard %s(bytes)%s", + strxf_limit(cfg->hard_byte_limit), _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "limit: "); - fprintf(fp, "soft "); - fprintf(fp, strxf_limit(cfg->soft_packet_limit)); - fprintf(fp, "(packets), hard "); - fprintf(fp, strxf_limit(cfg->hard_packet_limit)); - fprintf(fp, "(packets)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " limit: soft %s(packets),", + strxf_limit(cfg->soft_packet_limit)); + fprintf(fp, " hard %s(packets)%s", + strxf_limit(cfg->hard_packet_limit), _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "expire add: "); - fprintf(fp, "soft "); - fprintf(fp, "%llu", (unsigned long long) cfg->soft_add_expires_seconds); - fprintf(fp, "(sec), hard "); - fprintf(fp, "%llu", (unsigned long long) cfg->hard_add_expires_seconds); - fprintf(fp, "(sec)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " expire add: soft %llu(sec), hard %llu(sec)%s", + (unsigned long long) cfg->soft_add_expires_seconds, + (unsigned long long) cfg->hard_add_expires_seconds, + _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "expire use: "); - fprintf(fp, "soft "); - fprintf(fp, "%llu", (unsigned long long) cfg->soft_use_expires_seconds); - fprintf(fp, "(sec), hard "); - fprintf(fp, "%llu", (unsigned long long) cfg->hard_use_expires_seconds); - fprintf(fp, "(sec)"); - fprintf(fp, "%s", _SL_); + fprintf(fp, " expire use: soft %llu(sec), hard %llu(sec)%s", + (unsigned long long) cfg->soft_use_expires_seconds, + (unsigned long long) cfg->hard_use_expires_seconds, + _SL_); } if (cur) { if (prefix) fputs(prefix, fp); - fprintf(fp, "lifetime current:"); - fprintf(fp, "%s", _SL_); + fprintf(fp, "lifetime current:%s", _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "%llu(bytes), ", (unsigned long long) cur->bytes); - fprintf(fp, "%llu(packets)", (unsigned long long) cur->packets); - fprintf(fp, "%s", _SL_); + fprintf(fp, " %llu(bytes), %llu(packets)%s", + (unsigned long long) cur->bytes, + (unsigned long long) cur->packets, + _SL_); if (prefix) fputs(prefix, fp); - fprintf(fp, " "); - fprintf(fp, "add %s ", strxf_time(cur->add_time)); - fprintf(fp, "use %s", strxf_time(cur->use_time)); - fprintf(fp, "%s", _SL_); + fprintf(fp, " add %s ", strxf_time(cur->add_time)); + fprintf(fp, "use %s%s", strxf_time(cur->use_time), _SL_); } } From 24f38182441868f27aec03e82105eb008127e879 Mon Sep 17 00:00:00 2001 From: Sven Anders Date: Tue, 10 Nov 2009 09:07:26 -0800 Subject: [PATCH 03/59] Fix flushing code - rtnl_send_check I experienced an error, if I try to perform a ip route flush proto 4 with many routes in a complex environment, it gave me the following error: Failed to send flush request: Success Flush terminated --- lib/libnetlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index b68e2fdb..100dd407 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -137,8 +137,8 @@ int rtnl_send_check(struct rtnl_handle *rth, const char *buf, int len) fprintf(stderr, "ERROR truncated\n"); else errno = -err->error; + return -1; } - return -1; } return 0; From 7f03191fda39ff09640f093b7ad84f461ffd65b2 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 28 Oct 2009 20:50:48 +0100 Subject: [PATCH 04/59] iproute uses too small of a receive buffer It uses 1MB as receive buf limit by default (without increasing /proc/sys/net/core/rmem_max it will be limited by less however) and allows to specify the size manually using "-rcvbuf X" (-r is already used, so you need to specify at least -rc). Additionally rtnl_listen() continues on ENOBUFS after printing the error message. --- include/libnetlink.h | 2 ++ ip/ip.c | 16 +++++++++++++++- lib/libnetlink.c | 5 ++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/libnetlink.h b/include/libnetlink.h index 0e024682..61da15be 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -17,6 +17,8 @@ struct rtnl_handle __u32 dump; }; +extern int rcvbuf; + extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol); extern void rtnl_close(struct rtnl_handle *rth); diff --git a/ip/ip.c b/ip/ip.c index 2bd54b2a..b4c076aa 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -50,7 +50,8 @@ static void usage(void) " tunnel | maddr | mroute | monitor | xfrm }\n" " OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n" " -f[amily] { inet | inet6 | ipx | dnet | link } |\n" -" -o[neline] | -t[imestamp] | -b[atch] [filename] }\n"); +" -o[neline] | -t[imestamp] | -b[atch] [filename] |\n" +" -rc[vbuf] [size]}\n"); exit(-1); } @@ -213,6 +214,19 @@ int main(int argc, char **argv) if (argc <= 1) usage(); batch_file = argv[1]; + } else if (matches(opt, "-rcvbuf") == 0) { + unsigned int size; + + argc--; + argv++; + if (argc <= 1) + usage(); + if (get_unsigned(&size, argv[1], 0)) { + fprintf(stderr, "Invalid rcvbuf size '%s'\n", + argv[1]); + exit(-1); + } + rcvbuf = size; } else if (matches(opt, "-help") == 0) { usage(); } else { diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 100dd407..a6c03068 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -25,6 +25,8 @@ #include "libnetlink.h" +int rcvbuf = 1024 * 1024; + void rtnl_close(struct rtnl_handle *rth) { if (rth->fd >= 0) { @@ -38,7 +40,6 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, { socklen_t addr_len; int sndbuf = 32768; - int rcvbuf = 32768; memset(rth, 0, sizeof(*rth)); @@ -409,6 +410,8 @@ int rtnl_listen(struct rtnl_handle *rtnl, continue; fprintf(stderr, "netlink receive error %s (%d)\n", strerror(errno), errno); + if (errno == ENOBUFS) + continue; return -1; } if (status == 0) { From a7a9ddbb675b7fbd184c3ab40817265b0b207a23 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 6 Nov 2009 06:04:39 -0500 Subject: [PATCH 05/59] arpd/ifstat/nstat/rtacct: use daemon() A bunch of misc utils basically reimplement the daemon() function (the whole fork/close/chdir/etc...). Rather than do that, use daemon() as that will work under nommu Linux systems that lack fork(). Signed-off-by: Mike Frysinger --- misc/arpd.c | 24 +++--------------------- misc/ifstat.c | 8 ++++---- misc/nstat.c | 8 ++++---- misc/rtacct.c | 8 ++++---- 4 files changed, 15 insertions(+), 33 deletions(-) diff --git a/misc/arpd.c b/misc/arpd.c index 71cd082e..128c49d7 100644 --- a/misc/arpd.c +++ b/misc/arpd.c @@ -775,27 +775,9 @@ int main(int argc, char **argv) load_initial_table(); - if (1) { - int fd; - pid_t pid = fork(); - - if (pid > 0) - _exit(0); - if (pid < 0) { - perror("arpd: fork"); - goto do_abort; - } - - chdir("/"); - fd = open("/dev/null", O_RDWR); - if (fd >= 0) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); - } - setsid(); + if (daemon(0, 0)) { + perror("arpd: daemon"); + goto do_abort; } openlog("arpd", LOG_PID | LOG_CONS, LOG_DAEMON); diff --git a/misc/ifstat.c b/misc/ifstat.c index 68dfdeee..0ce8c928 100644 --- a/misc/ifstat.c +++ b/misc/ifstat.c @@ -663,10 +663,10 @@ int main(int argc, char *argv[]) perror("ifstat: listen"); exit(-1); } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); + if (daemon(0, 0)) { + perror("ifstat: daemon"); + exit(-1); + } signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); diff --git a/misc/nstat.c b/misc/nstat.c index 80e695fc..2e44ed25 100644 --- a/misc/nstat.c +++ b/misc/nstat.c @@ -513,10 +513,10 @@ int main(int argc, char *argv[]) perror("nstat: listen"); exit(-1); } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); + if (daemon(0, 0)) { + perror("nstat: daemon"); + exit(-1); + } signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); diff --git a/misc/rtacct.c b/misc/rtacct.c index eb3ea9ec..a247dfd2 100644 --- a/misc/rtacct.c +++ b/misc/rtacct.c @@ -524,10 +524,10 @@ int main(int argc, char *argv[]) perror("rtacct: listen"); exit(-1); } - if (fork()) - exit(0); - chdir("/"); - close(0); close(1); close(2); setsid(); + if (daemon(0, 0)) { + perror("rtacct: daemon"); + exit(-1); + } signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, sigchild); server_loop(fd); From f2e27cfb016e2465cd3f07e0b556058060702578 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 6 Nov 2009 06:09:22 -0500 Subject: [PATCH 06/59] support static-only systems The iptables code supports a "no shared libs" mode where it can be used without requiring dlfcn related functionality. This adds similar support to iproute2 so that it can easily be used on systems like nommu Linux (but obviously with a few limitations -- no dynamic plugins). Rather than modify every location that uses dlfcn.h, I hooked the dlfcn.h header with stub functions when shared library support is disabled. Then symbol lookup is done via a local static lookup table (which is generated automatically at build time) so that internal symbols can be found. Signed-off-by: Mike Frysinger --- Makefile | 5 +++++ genl/Makefile | 15 +++++++++++++++ genl/static-syms.c | 6 ++++++ include/dlfcn.h | 39 +++++++++++++++++++++++++++++++++++++++ ip/Makefile | 16 +++++++++++++++- ip/static-syms.c | 6 ++++++ tc/Makefile | 23 +++++++++++++++++++---- tc/m_ipt.c | 4 ++++ tc/static-syms.c | 6 ++++++ 9 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 genl/static-syms.c create mode 100644 include/dlfcn.h create mode 100644 ip/static-syms.c create mode 100644 tc/static-syms.c diff --git a/Makefile b/Makefile index 74e9d627..77a85c6e 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,12 @@ ARPDDIR=/var/lib/arpd # Path to db_185.h include DBM_INCLUDE:=$(ROOTDIR)/usr/include +SHARED_LIBS = y + DEFINES= -DRESOLVE_HOSTNAMES -DLIBDIR=\"$(LIBDIR)\" +ifneq ($(SHARED_LIBS),y) +DEFINES+= -DNO_SHARED_LIBS +endif #options if you have a bind>=4.9.4 libresolv (or, maybe, glibc) LDLIBS=-lresolv diff --git a/genl/Makefile b/genl/Makefile index 64358755..44bb83cd 100644 --- a/genl/Makefile +++ b/genl/Makefile @@ -1,6 +1,7 @@ GENLOBJ=genl.o include ../Config +SHARED_LIBS ?= y GENLMODULES := GENLMODULES += ctrl.o @@ -9,8 +10,10 @@ GENLOBJ += $(GENLMODULES) GENLLIB := +ifeq ($(SHARED_LIBS),y) LDFLAGS += -Wl,-export-dynamic LDLIBS += -lm -ldl +endif all: genl @@ -21,3 +24,15 @@ install: all clean: rm -f $(GENLOBJ) $(GENLLIB) genl + +ifneq ($(SHARED_LIBS),y) + +genl: static-syms.o +static-syms.o: static-syms.h +static-syms.h: $(wildcard *.c) + files="$^" ; \ + for s in `grep -B 3 '\ $@ + +endif diff --git a/genl/static-syms.c b/genl/static-syms.c new file mode 100644 index 00000000..1ed3a8a9 --- /dev/null +++ b/genl/static-syms.c @@ -0,0 +1,6 @@ +#include +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +} diff --git a/include/dlfcn.h b/include/dlfcn.h new file mode 100644 index 00000000..b0be5a0f --- /dev/null +++ b/include/dlfcn.h @@ -0,0 +1,39 @@ +/* + * Stub dlfcn implementation for systems that lack shared library support + * but obviously can still reference compiled-in symbols. + */ + +#ifndef NO_SHARED_LIBS +#include_next +#else + +#define RTLD_LAZY 0 +#define _FAKE_DLFCN_HDL (void *)0xbeefcafe + +static inline void *dlopen(const char *file, int flag) +{ + if (file == NULL) + return _FAKE_DLFCN_HDL; + else + return NULL; +} + +extern void *_dlsym(const char *sym); +static inline void *dlsym(void *handle, const char *sym) +{ + if (handle != _FAKE_DLFCN_HDL) + return NULL; + return _dlsym(sym); +} + +static inline char *dlerror(void) +{ + return NULL; +} + +static inline int dlclose(void *handle) +{ + return (handle == _FAKE_DLFCN_HDL) ? 0 : 1; +} + +#endif diff --git a/ip/Makefile b/ip/Makefile index 3c185cfb..51914e85 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -23,6 +23,20 @@ install: all clean: rm -f $(ALLOBJ) $(TARGETS) -LDLIBS += -ldl +SHARED_LIBS ?= y +ifeq ($(SHARED_LIBS),y) +LDLIBS += -ldl LDFLAGS += -Wl,-export-dynamic + +else + +ip: static-syms.o +static-syms.o: static-syms.h +static-syms.h: $(wildcard *.c) + files="$^" ; \ + for s in `grep -B 3 '\ $@ + +endif diff --git a/ip/static-syms.c b/ip/static-syms.c new file mode 100644 index 00000000..1ed3a8a9 --- /dev/null +++ b/ip/static-syms.c @@ -0,0 +1,6 @@ +#include +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +} diff --git a/tc/Makefile b/tc/Makefile index 3ff25358..027055cf 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -3,6 +3,7 @@ TCOBJ= tc.o tc_qdisc.o tc_class.o tc_filter.o tc_util.o \ m_ematch.o emp_ematch.yacc.o emp_ematch.lex.o include ../Config +SHARED_LIBS ?= y TCMODULES := TCMODULES += q_fifo.o @@ -57,7 +58,12 @@ else endif TCOBJ += $(TCMODULES) -LDLIBS += -L. -ltc -lm -ldl +LDLIBS += -L. -ltc -lm + +ifeq ($(SHARED_LIBS),y) +LDLIBS += -ldl +LDFLAGS += -Wl,-export-dynamic +endif TCLIB := tc_core.o TCLIB += tc_red.o @@ -72,9 +78,6 @@ ifeq ($(TC_CONFIG_ATM),y) TCSO += q_atm.so endif - -LDFLAGS += -Wl,-export-dynamic - YACC := bison LEX := flex @@ -108,3 +111,15 @@ q_atm.so: q_atm.c %.lex.c: %.l $(LEX) $(LEXFLAGS) -o$@ $< + +ifneq ($(SHARED_LIBS),y) + +tc: static-syms.o +static-syms.o: static-syms.h +static-syms.h: $(wildcard *.c) + files="$^" ; \ + for s in `grep -B 3 '\ $@ + +endif diff --git a/tc/m_ipt.c b/tc/m_ipt.c index d17d3245..99d9965a 100644 --- a/tc/m_ipt.c +++ b/tc/m_ipt.c @@ -226,6 +226,10 @@ get_target_name(const char *name) struct iptables_target *m; char path[strlen(lib_dir) + sizeof ("/libipt_.so") + strlen(name)]; +#ifdef NO_SHARED_LIBS + return NULL; +#endif + new_name = malloc(strlen(name) + 1); lname = malloc(strlen(name) + 1); if (new_name) diff --git a/tc/static-syms.c b/tc/static-syms.c new file mode 100644 index 00000000..1ed3a8a9 --- /dev/null +++ b/tc/static-syms.c @@ -0,0 +1,6 @@ +#include +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +} From a6992a9c91e4dc8277e2790ca35c3873c498e964 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 10 Nov 2009 10:45:05 -0800 Subject: [PATCH 07/59] Add static-syms.h to ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8199aae6..e33227f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +static-syms.h Config *.o *.a From 05b4f8492b1f605e78e7ff961cb165a475f456bc Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 4 Nov 2009 04:26:34 +0000 Subject: [PATCH 08/59] tc: remove dlfcn.h from files that dont need it A bunch of source files look like they're copy & pasted from other files, and some include header files that they don't actually need. Since dlfcn has very specific usage (and is a pain on a static-only system), drop it where it isn't really needed. Signed-off-by: Mike Frysinger --- tc/em_cmp.c | 1 - tc/em_meta.c | 1 - tc/em_nbyte.c | 1 - tc/em_u32.c | 1 - tc/m_nat.c | 1 - tc/m_xt.c | 1 - 6 files changed, 6 deletions(-) diff --git a/tc/em_cmp.c b/tc/em_cmp.c index ce72a429..6addce07 100644 --- a/tc/em_cmp.c +++ b/tc/em_cmp.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/em_meta.c b/tc/em_meta.c index ee6034fb..033e29f2 100644 --- a/tc/em_meta.c +++ b/tc/em_meta.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/em_nbyte.c b/tc/em_nbyte.c index 242c361b..87f3e9d2 100644 --- a/tc/em_nbyte.c +++ b/tc/em_nbyte.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/em_u32.c b/tc/em_u32.c index 402bea0e..21ed70fd 100644 --- a/tc/em_u32.c +++ b/tc/em_u32.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "m_ematch.h" diff --git a/tc/m_nat.c b/tc/m_nat.c index 6e7fd055..01ec0328 100644 --- a/tc/m_nat.c +++ b/tc/m_nat.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "utils.h" #include "tc_util.h" #include diff --git a/tc/m_xt.c b/tc/m_xt.c index 0fe61899..0c7ec604 100644 --- a/tc/m_xt.c +++ b/tc/m_xt.c @@ -25,7 +25,6 @@ #include "tc_util.h" #include #include -#include #include #include #include From 5e2f74a75cbb50445a9300d8793bb2ccf2459943 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 13 Nov 2009 14:18:35 -0800 Subject: [PATCH 09/59] Add more files to gitignore Ignore files from cscope, patch, etc. --- .gitignore | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.gitignore b/.gitignore index e33227f4..7d77a64b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,15 @@ Config *.a *.so *~ +\#*# +# cscope +cscope.* +ncscope.* +# for patch generation +*.diff +*.patch +*.orig +*.rej +# for quilt +patches +series From bba2fcd3fade22fcd93c56cb9d4646ea980c65c7 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 13 Nov 2009 14:20:41 -0800 Subject: [PATCH 10/59] Ignore GDB related files Revised version of Mike's original patch --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 7d77a64b..5ee20805 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,7 @@ ncscope.* # for quilt patches series +# for gdb +.gdbinit +.gdb_history +*.gdb From 5a326efed08ac3e6a9652180d35e194d6ccb6a1a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 17 Nov 2009 10:04:57 -0800 Subject: [PATCH 11/59] iproute2-091117 --- include/SNAPSHOT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index 4001bf09..ee5dad8e 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "090324"; +static const char SNAPSHOT[] = "091117"; From e03dcc040d47e87991314991ba2f79af9fab2218 Mon Sep 17 00:00:00 2001 From: David Ward Date: Thu, 15 Oct 2009 14:53:21 -0400 Subject: [PATCH 12/59] iproute2: Support 20-byte link layer address in idxmap Extend the link-layer address field from 8 to 20 bytes to support InfiniBand. Signed-off-by: David Ward --- lib/ll_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ll_map.c b/lib/ll_map.c index c1d61a9a..a96c59ea 100644 --- a/lib/ll_map.c +++ b/lib/ll_map.c @@ -31,7 +31,7 @@ struct idxmap int type; int alen; unsigned flags; - unsigned char addr[8]; + unsigned char addr[20]; char name[16]; }; From 232642c28c5320e6cf1e32f667f866c5f7372bfe Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 1 Dec 2009 15:49:48 -0800 Subject: [PATCH 13/59] Remove Changes: comments Discourage developers from putting change log in comments now that software has been under change control for 5 years. --- ip/ip.c | 5 ----- ip/ip6tunnel.c | 5 ----- ip/ipaddress.c | 2 -- ip/ipneigh.c | 4 ---- ip/iproute.c | 5 ----- ip/iprule.c | 4 ---- ip/iptunnel.c | 6 ------ lib/utils.c | 4 ---- tc/q_prio.c | 4 ---- tc/q_rr.c | 5 ----- 10 files changed, 44 deletions(-) diff --git a/ip/ip.c b/ip/ip.c index b4c076aa..ace8cc6f 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -7,11 +7,6 @@ * 2 of the License, or (at your option) any later version. * * Authors: Alexey Kuznetsov, - * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c index 8852a67a..203e4a3a 100644 --- a/ip/ip6tunnel.c +++ b/ip/ip6tunnel.c @@ -15,11 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* - * based on: - * $Id: s.ipv6tunnel.c 1.7 02/12/11 11:21:51+02:00 antti@traci.mipl.mediapoli.com $ - * - */ /* * Author: * Masahide NAKAMURA @USAGI diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 267ecb36..592d7c62 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -8,8 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * Changes: - * Laszlo Valko 990223: address label must be zero terminated */ #include diff --git a/ip/ipneigh.c b/ip/ipneigh.c index 30c7c72d..2d96ab7c 100644 --- a/ip/ipneigh.c +++ b/ip/ipneigh.c @@ -8,10 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include diff --git a/ip/iproute.c b/ip/iproute.c index bf0f31bd..82abbdac 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -8,11 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses - * Kunihiro Ishiguro 001102: rtnh_ifindex was not initialized */ #include diff --git a/ip/iprule.c b/ip/iprule.c index e1a943a2..20be990b 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -8,10 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include diff --git a/ip/iptunnel.c b/ip/iptunnel.c index 338d8bdf..dcd7ee6f 100644 --- a/ip/iptunnel.c +++ b/ip/iptunnel.c @@ -8,12 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses - * Rani Assaf 980930: do not allow key for ipip/sit - * Phil Karn 990408: "pmtudisc" flag */ #include diff --git a/lib/utils.c b/lib/utils.c index 0bb08325..a60d884e 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -8,10 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * - * Changes: - * - * Rani Assaf 980929: resolve addresses */ #include diff --git a/tc/q_prio.c b/tc/q_prio.c index 6883edb0..31a37cd8 100644 --- a/tc/q_prio.c +++ b/tc/q_prio.c @@ -8,10 +8,6 @@ * * Authors: Alexey Kuznetsov, * - * Changes: - * - * Ole Husgaard : 990513: prio2band map was always reset. - * J Hadi Salim : 990609: priomap fix. */ #include diff --git a/tc/q_rr.c b/tc/q_rr.c index 9335c470..9bb8c7de 100644 --- a/tc/q_rr.c +++ b/tc/q_rr.c @@ -8,11 +8,6 @@ * * Authors: PJ Waskiewicz, * Original Authors: Alexey Kuznetsov, (from PRIO) - * - * Changes: - * - * Ole Husgaard : 990513: prio2band map was always reset. - * J Hadi Salim : 990609: priomap fix. */ #include From 71e5815105fb0b86af7df9c719f7c106f05f29c0 Mon Sep 17 00:00:00 2001 From: Gilad Ben-Yossef Date: Tue, 6 Oct 2009 15:40:34 +0200 Subject: [PATCH 14/59] iproute2 add hoplimit parsing and update usage and documentation - Parse and handle the hoplimit ip route option and add it to the usage line and documentation. - Add the missing reordering ip route option to the usage line. - Add documentation for initcwnd ip route option. Tested by setting hoplimit and retreiving it via "show". Signed-off-by: Gilad Ben-Yossef [ported to HEAD, fixed a bug with hoplimit lock handling, added documentation] Signed-off-by: Ori Finkelman Signed-off-by: Yony Amit --- doc/ip-cref.tex | 13 +++++++++++++ ip/iproute.c | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex index bb4eb783..6ea44025 100644 --- a/doc/ip-cref.tex +++ b/doc/ip-cref.tex @@ -1324,7 +1324,17 @@ peers are allowed to send to us. If it is not given, Linux uses the value selected with \verb|sysctl| variable \verb|net/ipv4/tcp_reordering|. +\item \verb|hoplimit NUMBER| +--- [2.5.74+ only] Maximum number of hops on the path to this destination. + The default is the value selected with the \verb|sysctl| variable + \verb|net/ipv4/ip_default_ttl|. + +\item \verb|initcwnd NUMBER| +--- [2.5.70+ only] Initial congestion window size for connections to + this destination. Actual window size is this value multiplied by the + MSS (``Maximal Segment Size'') for same connection. The default is + zero, meaning to use the values specified in~\cite{RFC2414}. \item \verb|nexthop NEXTHOP| @@ -2653,6 +2663,9 @@ http://www.cisco.com/univercd/cc/td/doc/product/software/ios120. \bibitem{RFC-DHCP} R.~Droms. ``Dynamic Host Configuration Protocol.'', RFC-2131 +\bibitem{RFC2414} M.~Allman, S.~Floyd, C.~Partridge. +``Increasing TCP's Initial Window'', RFC-2414. + \end{thebibliography} diff --git a/ip/iproute.c b/ip/iproute.c index 82abbdac..b60926da 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -65,10 +65,10 @@ static void usage(void) fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n"); fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n"); fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n"); - fprintf(stderr, " [ rtt TIME ] [ rttvar TIME ]\n"); + fprintf(stderr, " [ rtt TIME ] [ rttvar TIME ] [reordering NUMBER ]\n"); fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n"); fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n"); - fprintf(stderr, " [ rto_min TIME ]\n"); + fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] \n"); fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n"); fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n"); fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); @@ -763,6 +763,18 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) if (get_unsigned(&mtu, *argv, 0)) invarg("\"mtu\" value is invalid\n", *argv); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); +#ifdef RTAX_HOPLIMIT + } else if (strcmp(*argv, "hoplimit") == 0) { + unsigned hoplimit; + NEXT_ARG(); + if (strcmp(*argv, "lock") == 0) { + mxlock |= (1< Date: Thu, 15 Oct 2009 14:53:13 -0400 Subject: [PATCH 15/59] iproute2: Add ll_index_to_addr function After calling ll_init_map, all of the information stored in the link-layer map can be retrieved by function calls (ll_index_to_*), except for the link-layer address. This patch fills the gap by adding a ll_index_to_addr function. Changes welcome. Signed-off-by: David Ward --- include/ll_map.h | 2 ++ lib/ll_map.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/ll_map.h b/include/ll_map.h index c4d5c6d1..752b8279 100644 --- a/include/ll_map.h +++ b/include/ll_map.h @@ -9,5 +9,7 @@ extern const char *ll_index_to_name(unsigned idx); extern const char *ll_idx_n2a(unsigned idx, char *buf); extern int ll_index_to_type(unsigned idx); extern unsigned ll_index_to_flags(unsigned idx); +extern unsigned ll_index_to_addr(unsigned idx, unsigned char *addr, + unsigned alen); #endif /* __LL_MAP_H__ */ diff --git a/lib/ll_map.c b/lib/ll_map.c index a96c59ea..5addf4a4 100644 --- a/lib/ll_map.c +++ b/lib/ll_map.c @@ -134,6 +134,27 @@ unsigned ll_index_to_flags(unsigned idx) return 0; } +unsigned ll_index_to_addr(unsigned idx, unsigned char *addr, + unsigned alen) +{ + struct idxmap *im; + + if (idx == 0) + return 0; + + for (im = idxmap[idx&0xF]; im; im = im->next) { + if (im->index == idx) { + if (alen > sizeof(im->addr)) + alen = sizeof(im->addr); + if (alen > im->alen) + alen = im->alen; + memcpy(addr, im->addr, alen); + return alen; + } + } + return 0; +} + unsigned ll_name_to_index(const char *name) { static char ncache[16]; From f4af851bac12b0a72515912d6e1458d41aa2e009 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Tue, 1 Dec 2009 15:58:44 -0800 Subject: [PATCH 16/59] ipv6: Add IFA_F_DADFAILED flag Add IFA_F_DADFAILED flag to denote an IPv6 address that has failed Duplicate Address Detection, that way tools like /sbin/ip can be more informative. 3: eth0: mtu 1500 qlen 1000 inet6 2001:db8::1/64 scope global tentative dadfailed valid_lft forever preferred_lft forever Signed-off-by: Brian Haley --- ip/ipaddress.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 592d7c62..f0add800 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -506,6 +506,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, fprintf(fp, "dynamic "); } else ifa->ifa_flags &= ~IFA_F_PERMANENT; + if (ifa->ifa_flags&IFA_F_DADFAILED) { + ifa->ifa_flags &= ~IFA_F_DADFAILED; + fprintf(fp, "dadfailed "); + } if (ifa->ifa_flags) fprintf(fp, "flags %02x ", ifa->ifa_flags); if (rta_tb[IFA_LABEL]) From 080b3ad42820e002b91ab4e3ddb728d2c6763b58 Mon Sep 17 00:00:00 2001 From: Mark Borst Date: Tue, 1 Dec 2009 16:15:15 -0800 Subject: [PATCH 17/59] iproute: "ip mroute show" doesn't show all output interfaces The command "ip mroute show" will only show the first Oif. mark@flappie:~$ ip mroute show (192.168.1.1, 224.0.0.123) Iif: _rename Oifs: eth1 mark@flappie:~$ cat /proc/net/ip_mr_cache Group Origin Iif Pkts Bytes Wrong Oifs 7B0000E0 0101A8C0 2 0 0 0 0:1 1:1 This shows 2 Oifs here. However, ipmroute.c, function read_mroute_list(), uses sscanf() with a %s mask for oiflist, which stops after the first whitespace (i.e. after Oif 0:1). The patch below fixes this to read until the newline (though I'm not sure whether this is the proper way to fix it). After this patch: mark@flappie:~/iproute-20090324/ip$ ./ip mroute show (192.168.1.1, 224.0.0.123) Iif: _rename Oifs: eth1 eth0 This patch originally submitted as http://bugs.debian.org/550097 Signed-off-by: Andreas Henriksson --- ip/ipmroute.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ip/ipmroute.c b/ip/ipmroute.c index 8f4b0612..977143cc 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -95,7 +95,8 @@ static void read_mroute_list(FILE *ofp) char obuf[256]; oiflist[0] = 0; - if (sscanf(buf, "%x%x%d%u%u%u%s", maddr.data, msrc.data, &vifi, + if (sscanf(buf, "%x%x%d%u%u%u %[^\n]", + maddr.data, msrc.data, &vifi, &pkts, &b, &w, oiflist) < 6) continue; From 6837f771edf49d5b19c12a2d2760234e86241c48 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Mon, 23 Nov 2009 11:03:52 +0100 Subject: [PATCH 18/59] iproute2: use -fPIC in lib/ The static libnetlink.a library is exposed to other users in Debian via the "iproute-dev" package. Apparently people are interested in using it in their shared libraries and would like to see the code be position independent. Patch below makes the code under lib/ build with -fPIC. See http://bugs.debian.org/547602 Signed-off-by: Andreas Henriksson --- lib/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Makefile b/lib/Makefile index bc270bff..da2f0fcb 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,3 +1,4 @@ +CFLAGS += -fPIC UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o From c90308ffc74d1e20c9de9521bfe6560b6b948650 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 23 Nov 2009 12:03:41 +0100 Subject: [PATCH 19/59] f_fw: fix compat mode The kernel takes a lack of options as indication that the fw classifier should operate in compatibility mode, where marks are mapped directly to classids. Commit e22b42a (tc mask patch) broke this by adding an empty TCA_OPTIONS attribute even if no handle is specified. Restore the old behaviour. Signed-off-by: Patrick McHardy --- tc/f_fw.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tc/f_fw.c b/tc/f_fw.c index b5117356..cc8ea2d8 100644 --- a/tc/f_fw.c +++ b/tc/f_fw.c @@ -38,15 +38,13 @@ static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **a struct tc_police tp; struct tcmsg *t = NLMSG_DATA(n); struct rtattr *tail; + __u32 mask = 0; + int mask_set = 0; memset(&tp, 0, sizeof(tp)); - tail = NLMSG_TAIL(n); - addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); - if (handle) { char *slash; - __u32 mask = 0; if ((slash = strchr(handle, '/')) != NULL) *slash = '\0'; if (get_u32(&t->tcm_handle, handle, 0)) { @@ -58,13 +56,19 @@ static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **a fprintf(stderr, "Illegal \"handle\" mask\n"); return -1; } - addattr32(n, MAX_MSG, TCA_FW_MASK, mask); + mask_set = 1; } } if (argc == 0) return 0; + tail = NLMSG_TAIL(n); + addattr_l(n, 4096, TCA_OPTIONS, NULL, 0); + + if (mask_set) + addattr32(n, MAX_MSG, TCA_FW_MASK, mask); + while (argc > 0) { if (matches(*argv, "classid") == 0 || matches(*argv, "flowid") == 0) { From 7a96e1997782044cdb834b6c086f6287d0e641c2 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Mon, 7 Dec 2009 13:12:36 +0100 Subject: [PATCH 20/59] iproute: make ss --help output to stdout Peter Palfrader said in http://bugs.debian.org/545008 that "--help output, if explicitly requested, should go to stdout, not stderr." which this patch fixes. Additionally, the exit code was adjusted to success if help was explicitly requested. (Syntax error still outputs to stderr and has the same exit code.) Signed-off-by: Andreas Henriksson --- misc/ss.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/misc/ss.c b/misc/ss.c index ac7f4110..8a9663cf 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -2331,12 +2331,9 @@ int print_summary(void) return 0; } - -static void usage(void) __attribute__((noreturn)); - -static void usage(void) +static void _usage(FILE *dest) { - fprintf(stderr, + fprintf(dest, "Usage: ss [ OPTIONS ]\n" " ss [ OPTIONS ] [ FILTER ]\n" " -h, --help this message\n" @@ -2368,6 +2365,19 @@ static void usage(void) " -F, --filter=FILE read filter information from FILE\n" " FILTER := [ state TCP-STATE ] [ EXPRESSION ]\n" ); +} + +static void help(void) __attribute__((noreturn)); +static void help(void) +{ + _usage(stdout); + exit(0); +} + +static void usage(void) __attribute__((noreturn)); +static void usage(void) +{ + _usage(stderr); exit(-1); } @@ -2514,7 +2524,7 @@ int main(int argc, char *argv[]) else if (strcmp(optarg, "netlink") == 0) preferred_family = AF_NETLINK; else if (strcmp(optarg, "help") == 0) - usage(); + help(); else { fprintf(stderr, "ss: \"%s\" is invalid family\n", optarg); usage(); @@ -2596,6 +2606,7 @@ int main(int argc, char *argv[]) exit(0); case 'h': case '?': + help(); default: usage(); } From 80d689d055b2169b390a7cd4ca2c01ba871d02a2 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Wed, 2 Dec 2009 16:11:21 +0100 Subject: [PATCH 21/59] Keep the old tc/ipt/xt module for compatibility. Move the file and rename the configure flags. The file is being kept around for iptables < 1.4.5 compatibility. Signed-off-by: Andreas Henriksson --- configure | 4 ++-- tc/Makefile | 15 ++++++++++----- tc/{m_xt.c => m_xt_old.c} | 0 3 files changed, 12 insertions(+), 7 deletions(-) rename tc/{m_xt.c => m_xt_old.c} (100%) diff --git a/configure b/configure index df40370a..f3b79b25 100755 --- a/configure +++ b/configure @@ -53,7 +53,7 @@ gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl >/dev/null 2>&1 if [ $? -eq 0 ] then - echo "TC_CONFIG_XT:=y" >>Config + echo "TC_CONFIG_XT_OLD:=y" >>Config echo "using xtables seems no need for internal.h" else echo "failed test 2" @@ -86,7 +86,7 @@ gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl >/dev/null 2>&1 if [ $? -eq 0 ] then echo "using xtables instead of iptables (need for internal.h)" - echo "TC_CONFIG_XT_H:=y" >>Config + echo "TC_CONFIG_XT_OLD_H:=y" >>Config else echo "failed test 3 using iptables" diff --git a/tc/Makefile b/tc/Makefile index 027055cf..f3dd2b76 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -48,12 +48,17 @@ ifeq ($(TC_CONFIG_XT),y) TCMODULES += m_xt.o LDLIBS += -lxtables else - ifeq ($(TC_CONFIG_XT_H),y) - CFLAGS += -DTC_CONFIG_XT_H - TCMODULES += m_xt.o - LDLIBS += -lxtables + ifeq ($(TC_CONFIG_XT_OLD),y) + TCMODULES += m_xt_old.o + LDLIBS += -lxtables else - TCMODULES += m_ipt.o + ifeq ($(TC_CONFIG_XT_OLD_H),y) + CFLAGS += -DTC_CONFIG_XT_H + TCMODULES += m_xt_old.o + LDLIBS += -lxtables + else + TCMODULES += m_ipt.o + endif endif endif diff --git a/tc/m_xt.c b/tc/m_xt_old.c similarity index 100% rename from tc/m_xt.c rename to tc/m_xt_old.c From a36ceb85d7ae6a9742c35417e80ae837ce9f146d Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Wed, 2 Dec 2009 16:11:50 +0100 Subject: [PATCH 22/59] Add new (iptables 1.4.5 compatible) tc/ipt/xt module. Add a new cleaned up m_xt.c based on m_xt_old.c The new m_xt.c has been updated to use the new names and new api that xtables exposes in iptables 1.4.5. All the old internal api cruft has also been dropped. Additionally, a configure script test is added to check for the new xtables api and set the TC_CONFIG_XT flag in Config. (tc/Makefile already handles this flag in previous commit.) Signed-off-by: Andreas Henriksson --- configure | 27 +++++ tc/m_xt.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 373 insertions(+) create mode 100644 tc/m_xt.c diff --git a/configure b/configure index f3b79b25..4fda7cba 100755 --- a/configure +++ b/configure @@ -28,6 +28,33 @@ rm -f /tmp/atmtest.c /tmp/atmtest echo -n " IPT " +#check if we have xtables from iptables >= 1.4.5. +cat >/tmp/ipttest.c < +#include +static struct xtables_globals test_globals = { + .option_offset = 0, + .program_name = "tc-ipt", + .program_version = XTABLES_VERSION, + .orig_opts = NULL, + .opts = NULL, + .exit_err = NULL, +}; + +int main(int argc, char **argv) +{ + xtables_init_all(&test_globals, NFPROTO_IPV4); + return 0; +} + +EOF + +if gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl -lxtables >/dev/null 2>&1 +then + echo "TC_CONFIG_XT:=y" >>Config + echo "using xtables instead of iptables" +fi + #check if we need dont our internal header .. cat >/tmp/ipttest.c < diff --git a/tc/m_xt.c b/tc/m_xt.c new file mode 100644 index 00000000..3972d2d2 --- /dev/null +++ b/tc/m_xt.c @@ -0,0 +1,346 @@ +/* + * m_xt.c xtables based targets + * utilities mostly ripped from iptables + * + * This program is free software; you can distribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: J Hadi Salim (hadi@cyberus.ca) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "tc_util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef XT_LIB_DIR +# define XT_LIB_DIR "/lib/xtables" +#endif + +static const char *tname = "mangle"; + +char *lib_dir; + +static const char *ipthooks[] = { + "NF_IP_PRE_ROUTING", + "NF_IP_LOCAL_IN", + "NF_IP_FORWARD", + "NF_IP_LOCAL_OUT", + "NF_IP_POST_ROUTING", +}; + +static struct option original_opts[] = { + { + .name = "jump", + .has_arg = 1, + .val = 'j' + }, + {0, 0, 0, 0} +}; + +static struct xtables_globals tcipt_globals = { + .option_offset = 0, + .program_name = "tc-ipt", + .program_version = "0.2", + .orig_opts = original_opts, + .opts = original_opts, + .exit_err = NULL, +}; + +/* + * we may need to check for version mismatch +*/ +int +build_st(struct xtables_target *target, struct xt_entry_target *t) +{ + + size_t size = + XT_ALIGN(sizeof (struct xt_entry_target)) + target->size; + + if (NULL == t) { + target->t = xtables_calloc(1, size); + target->t->u.target_size = size; + strcpy(target->t->u.user.name, target->name); + xtables_set_revision(target->t->u.user.name, target->revision); + + if (target->init != NULL) + target->init(target->t); + } else { + target->t = t; + } + return 0; + +} + +inline void set_lib_dir(void) +{ + + lib_dir = getenv("XTABLES_LIBDIR"); + if (!lib_dir) { + lib_dir = getenv("IPTABLES_LIB_DIR"); + if (lib_dir) + fprintf(stderr, "using deprecated IPTABLES_LIB_DIR \n"); + } + if (lib_dir == NULL) + lib_dir = XT_LIB_DIR; + +} + +static int parse_ipt(struct action_util *a,int *argc_p, + char ***argv_p, int tca_id, struct nlmsghdr *n) +{ + struct xtables_target *m = NULL; + struct ipt_entry fw; + struct rtattr *tail; + int c; + int rargc = *argc_p; + char **argv = *argv_p; + int argc = 0, iargc = 0; + char k[16]; + int res = -1; + int size = 0; + int iok = 0, ok = 0; + __u32 hook = 0, index = 0; + res = 0; + + xtables_init_all(&tcipt_globals, NFPROTO_IPV4); + set_lib_dir(); + + { + int i; + for (i = 0; i < rargc; i++) { + if (NULL == argv[i] || 0 == strcmp(argv[i], "action")) { + break; + } + } + iargc = argc = i; + } + + if (argc <= 2) { + fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc); + return -1; + } + + while (1) { + c = getopt_long(argc, argv, "j:", tcipt_globals.opts, NULL); + if (c == -1) + break; + switch (c) { + case 'j': + m = xtables_find_target(optarg, XTF_TRY_LOAD); + if (NULL != m) { + + if (0 > build_st(m, NULL)) { + printf(" %s error \n", m->name); + return -1; + } + tcipt_globals.opts = + xtables_merge_options(tcipt_globals.opts, + m->extra_opts, + &m->option_offset); + } else { + fprintf(stderr," failed to find target %s\n\n", optarg); + return -1; + } + ok++; + break; + + default: + memset(&fw, 0, sizeof (fw)); + if (m) { + m->parse(c - m->option_offset, argv, 0, + &m->tflags, NULL, &m->t); + } else { + fprintf(stderr," failed to find target %s\n\n", optarg); + return -1; + + } + ok++; + break; + + } + } + + if (iargc > optind) { + if (matches(argv[optind], "index") == 0) { + if (get_u32(&index, argv[optind + 1], 10)) { + fprintf(stderr, "Illegal \"index\"\n"); + xtables_free_opts(1); + return -1; + } + iok++; + + optind += 2; + } + } + + if (!ok && !iok) { + fprintf(stderr," ipt Parser BAD!! (%s)\n", *argv); + return -1; + } + + /* check that we passed the correct parameters to the target */ + if (m && m->final_check) + m->final_check(m->tflags); + + { + struct tcmsg *t = NLMSG_DATA(n); + if (t->tcm_parent != TC_H_ROOT + && t->tcm_parent == TC_H_MAJ(TC_H_INGRESS)) { + hook = NF_IP_PRE_ROUTING; + } else { + hook = NF_IP_POST_ROUTING; + } + } + + tail = NLMSG_TAIL(n); + addattr_l(n, MAX_MSG, tca_id, NULL, 0); + fprintf(stdout, "tablename: %s hook: %s\n ", tname, ipthooks[hook]); + fprintf(stdout, "\ttarget: "); + + if (m) + m->print(NULL, m->t, 0); + fprintf(stdout, " index %d\n", index); + + if (strlen(tname) > 16) { + size = 16; + k[15] = 0; + } else { + size = 1 + strlen(tname); + } + strncpy(k, tname, size); + + addattr_l(n, MAX_MSG, TCA_IPT_TABLE, k, size); + addattr_l(n, MAX_MSG, TCA_IPT_HOOK, &hook, 4); + addattr_l(n, MAX_MSG, TCA_IPT_INDEX, &index, 4); + if (m) + addattr_l(n, MAX_MSG, TCA_IPT_TARG, m->t, m->t->u.target_size); + tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; + + argc -= optind; + argv += optind; + *argc_p = rargc - iargc; + *argv_p = argv; + + optind = 0; + xtables_free_opts(1); + /* Clear flags if target will be used again */ + m->tflags=0; + m->used=0; + /* Free allocated memory */ + if (m->t) + free(m->t); + + + return 0; + +} + +static int +print_ipt(struct action_util *au,FILE * f, struct rtattr *arg) +{ + struct rtattr *tb[TCA_IPT_MAX + 1]; + struct xt_entry_target *t = NULL; + + if (arg == NULL) + return -1; + + xtables_init_all(&tcipt_globals, NFPROTO_IPV4); + set_lib_dir(); + + parse_rtattr_nested(tb, TCA_IPT_MAX, arg); + + if (tb[TCA_IPT_TABLE] == NULL) { + fprintf(f, "[NULL ipt table name ] assuming mangle "); + } else { + fprintf(f, "tablename: %s ", + (char *) RTA_DATA(tb[TCA_IPT_TABLE])); + } + + if (tb[TCA_IPT_HOOK] == NULL) { + fprintf(f, "[NULL ipt hook name ]\n "); + return -1; + } else { + __u32 hook; + hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]); + fprintf(f, " hook: %s \n", ipthooks[hook]); + } + + if (tb[TCA_IPT_TARG] == NULL) { + fprintf(f, "\t[NULL ipt target parameters ] \n"); + return -1; + } else { + struct xtables_target *m = NULL; + t = RTA_DATA(tb[TCA_IPT_TARG]); + m = xtables_find_target(t->u.user.name, XTF_TRY_LOAD); + if (NULL != m) { + if (0 > build_st(m, t)) { + fprintf(stderr, " %s error \n", m->name); + return -1; + } + + tcipt_globals.opts = + xtables_merge_options(tcipt_globals.opts, + m->extra_opts, + &m->option_offset); + } else { + fprintf(stderr, " failed to find target %s\n\n", + t->u.user.name); + return -1; + } + fprintf(f, "\ttarget "); + m->print(NULL, m->t, 0); + if (tb[TCA_IPT_INDEX] == NULL) { + fprintf(f, " [NULL ipt target index ]\n"); + } else { + __u32 index; + index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]); + fprintf(f, " \n\tindex %d", index); + } + + if (tb[TCA_IPT_CNT]) { + struct tc_cnt *c = RTA_DATA(tb[TCA_IPT_CNT]);; + fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt); + } + if (show_stats) { + if (tb[TCA_IPT_TM]) { + struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]); + print_tm(f,tm); + } + } + fprintf(f, " \n"); + + } + xtables_free_opts(1); + + return 0; +} + +struct action_util ipt_action_util = { + .id = "ipt", + .parse_aopt = parse_ipt, + .print_aopt = print_ipt, +}; + From b49240ec7eab91418d2f090536bf8cd2205988d6 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 3 Dec 2009 12:08:27 +1100 Subject: [PATCH 23/59] flush secondary addresses before primary ones Unless promote_secondaries has been active deleting the primary address of an interface will automatically delete all the secondary addresses. In the case where ip flush requests the primary then secondary addresses to be removed - which is the order the addresses are returned by the kernel - this will cause an error as by the time the request to remove a secondary address is made it will be missing as it will have been deleted in the course of deleting the primary address. This approach to solving this problem orders requests for the deletion of secondary addresses before primary ones providing rtnl_dump_filter_l(), a version of rtnl_dump_filter() that iterates over a list of filters. And by providing two specialised filters print_addrinfo_secondary() and print_addrinfo_primary(). rtnl_dump_filter_l() first iterates over all addresses using print_addrinfo_secondary(), which appends secondary addresses to the request buffer. Then again using print_addrinfo_primary() which appends primary addresses. This approach should work regardless of it promote_secondaries is active or not. And regardless of if any primary of secondary addresses are present or not. Signed-off-by: Simon Horman --- include/libnetlink.h | 12 +++++++ ip/ipaddress.c | 43 +++++++++++++++++++++- lib/libnetlink.c | 86 ++++++++++++++++++++++++++------------------ 3 files changed, 105 insertions(+), 36 deletions(-) diff --git a/include/libnetlink.h b/include/libnetlink.h index 61da15be..07bd707e 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -27,10 +27,22 @@ extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int l typedef int (*rtnl_filter_t)(const struct sockaddr_nl *, struct nlmsghdr *n, void *); + +struct rtnl_dump_filter_arg +{ + rtnl_filter_t filter; + void *arg1; + rtnl_filter_t junk; + void *arg2; +}; + +extern int rtnl_dump_filter_l(struct rtnl_handle *rth, + const struct rtnl_dump_filter_arg *arg); extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter, void *arg1, rtnl_filter_t junk, void *arg2); + extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned groups, struct nlmsghdr *answer, rtnl_filter_t junk, diff --git a/ip/ipaddress.c b/ip/ipaddress.c index f0add800..c638ca74 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -539,6 +539,27 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, return 0; } +int print_addrinfo_primary(const struct sockaddr_nl *who, struct nlmsghdr *n, + void *arg) +{ + struct ifaddrmsg *ifa = NLMSG_DATA(n); + + if (!ifa->ifa_flags & IFA_F_SECONDARY) + return 0; + + return print_addrinfo(who, n, arg); +} + +int print_addrinfo_secondary(const struct sockaddr_nl *who, struct nlmsghdr *n, + void *arg) +{ + struct ifaddrmsg *ifa = NLMSG_DATA(n); + + if (ifa->ifa_flags & IFA_F_SECONDARY) + return 0; + + return print_addrinfo(who, n, arg); +} struct nlmsg_list { @@ -700,12 +721,32 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush) filter.flushe = sizeof(flushb); while (round < MAX_ROUNDS) { + const struct rtnl_dump_filter_arg a[3] = { + { + .filter = print_addrinfo_secondary, + .arg1 = stdout, + .junk = NULL, + .arg2 = NULL + }, + { + .filter = print_addrinfo_primary, + .arg1 = stdout, + .junk = NULL, + .arg2 = NULL + }, + { + .filter = NULL, + .arg1 = NULL, + .junk = NULL, + .arg2 = NULL + }, + }; if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { perror("Cannot send dump request"); exit(1); } filter.flushed = 0; - if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { + if (rtnl_dump_filter_l(&rth, a) < 0) { fprintf(stderr, "Flush terminated\n"); exit(1); } diff --git a/lib/libnetlink.c b/lib/libnetlink.c index a6c03068..4ba60190 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -172,11 +172,8 @@ int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) return sendmsg(rth->fd, &msg, 0); } -int rtnl_dump_filter(struct rtnl_handle *rth, - rtnl_filter_t filter, - void *arg1, - rtnl_filter_t junk, - void *arg2) +int rtnl_dump_filter_l(struct rtnl_handle *rth, + const struct rtnl_dump_filter_arg *arg) { struct sockaddr_nl nladdr; struct iovec iov; @@ -191,7 +188,7 @@ int rtnl_dump_filter(struct rtnl_handle *rth, iov.iov_base = buf; while (1) { int status; - struct nlmsghdr *h; + const struct rtnl_dump_filter_arg *a; iov.iov_len = sizeof(buf); status = recvmsg(rth->fd, &msg, 0); @@ -209,40 +206,45 @@ int rtnl_dump_filter(struct rtnl_handle *rth, return -1; } - h = (struct nlmsghdr*)buf; - while (NLMSG_OK(h, status)) { - int err; + for (a = arg; a->filter; a++) { + struct nlmsghdr *h = (struct nlmsghdr*)buf; - if (nladdr.nl_pid != 0 || - h->nlmsg_pid != rth->local.nl_pid || - h->nlmsg_seq != rth->dump) { - if (junk) { - err = junk(&nladdr, h, arg2); - if (err < 0) - return err; - } - goto skip_it; - } + while (NLMSG_OK(h, status)) { + int err; - if (h->nlmsg_type == NLMSG_DONE) - return 0; - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { - fprintf(stderr, "ERROR truncated\n"); - } else { - errno = -err->error; - perror("RTNETLINK answers"); + if (nladdr.nl_pid != 0 || + h->nlmsg_pid != rth->local.nl_pid || + h->nlmsg_seq != rth->dump) { + if (a->junk) { + err = a->junk(&nladdr, h, + a->arg2); + if (err < 0) + return err; + } + goto skip_it; } - return -1; - } - err = filter(&nladdr, h, arg1); - if (err < 0) - return err; + + if (h->nlmsg_type == NLMSG_DONE) + return 0; + if (h->nlmsg_type == NLMSG_ERROR) { + struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); + if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { + fprintf(stderr, + "ERROR truncated\n"); + } else { + errno = -err->error; + perror("RTNETLINK answers"); + } + return -1; + } + err = a->filter(&nladdr, h, a->arg1); + if (err < 0) + return err; skip_it: - h = NLMSG_NEXT(h, status); - } + h = NLMSG_NEXT(h, status); + } + } while (0); if (msg.msg_flags & MSG_TRUNC) { fprintf(stderr, "Message truncated\n"); continue; @@ -254,6 +256,20 @@ skip_it: } } +int rtnl_dump_filter(struct rtnl_handle *rth, + rtnl_filter_t filter, + void *arg1, + rtnl_filter_t junk, + void *arg2) +{ + const struct rtnl_dump_filter_arg a[2] = { + { .filter = filter, .arg1 = arg1, .junk = junk, .arg2 = arg2 }, + { .filter = NULL, .arg1 = NULL, .junk = NULL, .arg2 = NULL } + }; + + return rtnl_dump_filter_l(rth, a); +} + int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned groups, struct nlmsghdr *answer, rtnl_filter_t junk, From 985f4578c6f14bb85100613776c36cecd26e0d2b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sat, 26 Dec 2009 10:20:50 -0800 Subject: [PATCH 24/59] Fix warning about strtod() return value --- tc/q_netem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/q_netem.c b/tc/q_netem.c index d06932e8..33b3d2a4 100644 --- a/tc/q_netem.c +++ b/tc/q_netem.c @@ -100,8 +100,8 @@ static int get_distribution(const char *type, __s16 *data, int maxdata) static int isnumber(const char *arg) { char *p; - (void) strtod(arg, &p); - return (p != arg); + + return strtod(arg, &p) != 0 || p != arg; } #define NEXT_IS_NUMBER() (NEXT_ARG_OK() && isnumber(argv[1])) From 896ebd6c705651abe0a6eedc9c6158a5db6e38d3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sat, 26 Dec 2009 10:21:13 -0800 Subject: [PATCH 25/59] Fix warning about sprintf() and NSTAT_HIST The environment variable could contain format characters, causing problems. Better to just use it directly. --- misc/nstat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/nstat.c b/misc/nstat.c index 2e44ed25..4f73c628 100644 --- a/misc/nstat.c +++ b/misc/nstat.c @@ -445,7 +445,7 @@ static void usage(void) int main(int argc, char *argv[]) { - char hist_name[128]; + char *hist_name; struct sockaddr_un sun; FILE *hist_fp = NULL; int ch; @@ -526,10 +526,10 @@ int main(int argc, char *argv[]) patterns = argv; npatterns = argc; - if (getenv("NSTAT_HISTORY")) - snprintf(hist_name, sizeof(hist_name), getenv("NSTAT_HISTORY")); - else + if ((hist_name = getenv("NSTAT_HISTORY")) == NULL) { + hist_name = malloc(128); sprintf(hist_name, "/tmp/.nstat.u%d", getuid()); + } if (reset_history) unlink(hist_name); From f1a0125bc090a9310a2a86adc9acf59fc417d44a Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Wed, 2 Dec 2009 05:12:30 +0000 Subject: [PATCH 26/59] Slightly improve the configure script. Split up in functions. Make XT checks bail if previous XT check was successful. This result improves the output of the configure script to not indicate using iptables only because the last test failed (when previous ones could have already succeded). Signed-off-by: Andreas Henriksson --- configure | 66 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/configure b/configure index 4fda7cba..a903bb0c 100755 --- a/configure +++ b/configure @@ -3,11 +3,8 @@ # INCLUDE=${1:-"$PWD/include"} -echo "# Generated config based on" $INCLUDE >Config - -echo "TC schedulers" - -echo -n " ATM " +function check_atm +{ cat >/tmp/atmtest.c < int main(int argc, char **argv) { @@ -25,9 +22,10 @@ else echo no fi rm -f /tmp/atmtest.c /tmp/atmtest +} -echo -n " IPT " - +function check_xt +{ #check if we have xtables from iptables >= 1.4.5. cat >/tmp/ipttest.c < @@ -52,7 +50,17 @@ EOF if gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl -lxtables >/dev/null 2>&1 then echo "TC_CONFIG_XT:=y" >>Config - echo "using xtables instead of iptables" + echo "using xtables" +fi +rm -f /tmp/ipttest.c /tmp/ipttest +} + +function check_xt_old +{ +# bail if previous XT checks has already succeded. +if grep TC_CONFIG_XT Config > /dev/null +then + return fi #check if we need dont our internal header .. @@ -81,9 +89,17 @@ gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl >/dev/null 2>&1 if [ $? -eq 0 ] then echo "TC_CONFIG_XT_OLD:=y" >>Config - echo "using xtables seems no need for internal.h" -else - echo "failed test 2" + echo "using old xtables (no need for xt-internal.h)" +fi +rm -f /tmp/ipttest.c /tmp/ipttest +} + +function check_xt_old_internal_h +{ +# bail if previous XT checks has already succeded. +if grep TC_CONFIG_XT Config > /dev/null +then + return fi #check if we need our own internal.h @@ -112,10 +128,30 @@ gcc -I$INCLUDE $IPTC -o /tmp/ipttest /tmp/ipttest.c $IPTL -ldl >/dev/null 2>&1 if [ $? -eq 0 ] then - echo "using xtables instead of iptables (need for internal.h)" + echo "using old xtables with xt-internal.h" echo "TC_CONFIG_XT_OLD_H:=y" >>Config - -else - echo "failed test 3 using iptables" fi rm -f /tmp/ipttest.c /tmp/ipttest +} + +function check_ipt +{ + if ! grep TC_CONFIG_XT Config > /dev/null + then + echo "using iptables" + fi +} + +echo "# Generated config based on" $INCLUDE >Config + +echo "TC schedulers" + +echo -n " ATM " +check_atm + +echo -n " IPT " +check_xt +check_xt_old +check_xt_old_internal_h +check_ipt + From abdd9bf7c4a69a41c67432ca28f690463e6abd6b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sat, 26 Dec 2009 10:26:44 -0800 Subject: [PATCH 27/59] iproute2-091226 --- include/SNAPSHOT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index ee5dad8e..4696bfe8 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "091117"; +static const char SNAPSHOT[] = "091226"; From ab322673298bd0b8927cdd9d11f3d36af5941b93 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sat, 26 Dec 2009 11:02:25 -0800 Subject: [PATCH 28/59] Update exported kernel headers These corespond with 2.6.33-rc2 --- include/linux/fib_rules.h | 17 ++-- include/linux/gen_stats.h | 15 +-- include/linux/if.h | 16 ++-- include/linux/if_addr.h | 9 +- include/linux/if_addrlabel.h | 6 +- include/linux/if_arp.h | 3 +- include/linux/if_link.h | 42 +++++---- include/linux/if_tunnel.h | 17 +++- include/linux/if_vlan.h | 1 + include/linux/neighbour.h | 18 ++-- include/linux/netdevice.h | 3 +- include/linux/netfilter/x_tables.h | 21 ++--- include/linux/netfilter/xt_tcpudp.h | 6 +- include/linux/netfilter_ipv4/ip_tables.h | 15 +-- include/linux/netlink.h | 15 +-- include/linux/pkt_cls.h | 84 ++++++----------- include/linux/pkt_sched.h | 111 ++++++++--------------- include/linux/rtnetlink.h | 57 ++++-------- include/linux/tc_act/tc_gact.h | 9 +- include/linux/tc_act/tc_ipt.h | 3 +- include/linux/tc_act/tc_mirred.h | 6 +- include/linux/tc_act/tc_nat.h | 6 +- include/linux/tc_act/tc_pedit.h | 9 +- include/linux/tc_act/tc_skbedit.h | 2 + include/linux/tc_ematch/tc_em_cmp.h | 6 +- include/linux/tc_ematch/tc_em_meta.h | 15 +-- include/linux/tc_ematch/tc_em_nbyte.h | 3 +- include/linux/xfrm.h | 35 ++++--- 28 files changed, 212 insertions(+), 338 deletions(-) diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h index 87b606b6..51da65b6 100644 --- a/include/linux/fib_rules.h +++ b/include/linux/fib_rules.h @@ -8,13 +8,14 @@ #define FIB_RULE_PERMANENT 0x00000001 #define FIB_RULE_INVERT 0x00000002 #define FIB_RULE_UNRESOLVED 0x00000004 -#define FIB_RULE_DEV_DETACHED 0x00000008 +#define FIB_RULE_IIF_DETACHED 0x00000008 +#define FIB_RULE_DEV_DETACHED FIB_RULE_IIF_DETACHED +#define FIB_RULE_OIF_DETACHED 0x00000010 /* try to find source address in routing lookups */ #define FIB_RULE_FIND_SADDR 0x00010000 -struct fib_rule_hdr -{ +struct fib_rule_hdr { __u8 family; __u8 dst_len; __u8 src_len; @@ -28,12 +29,12 @@ struct fib_rule_hdr __u32 flags; }; -enum -{ +enum { FRA_UNSPEC, FRA_DST, /* destination address */ FRA_SRC, /* source address */ - FRA_IFNAME, /* interface name */ + FRA_IIFNAME, /* interface name */ +#define FRA_IFNAME FRA_IIFNAME FRA_GOTO, /* target to jump to (FR_ACT_GOTO) */ FRA_UNUSED2, FRA_PRIORITY, /* priority/preference */ @@ -47,13 +48,13 @@ enum FRA_UNUSED8, FRA_TABLE, /* Extended table id */ FRA_FWMASK, /* mask for netfilter mark */ + FRA_OIFNAME, __FRA_MAX }; #define FRA_MAX (__FRA_MAX - 1) -enum -{ +enum { FR_ACT_UNSPEC, FR_ACT_TO_TBL, /* Pass to fixed table */ FR_ACT_GOTO, /* Jump to another rule */ diff --git a/include/linux/gen_stats.h b/include/linux/gen_stats.h index 710e9010..552c8a0a 100644 --- a/include/linux/gen_stats.h +++ b/include/linux/gen_stats.h @@ -18,13 +18,11 @@ enum { * @bytes: number of seen bytes * @packets: number of seen packets */ -struct gnet_stats_basic -{ +struct gnet_stats_basic { __u64 bytes; __u32 packets; }; -struct gnet_stats_basic_packed -{ +struct gnet_stats_basic_packed { __u64 bytes; __u32 packets; } __attribute__ ((packed)); @@ -34,8 +32,7 @@ struct gnet_stats_basic_packed * @bps: current byte rate * @pps: current packet rate */ -struct gnet_stats_rate_est -{ +struct gnet_stats_rate_est { __u32 bps; __u32 pps; }; @@ -48,8 +45,7 @@ struct gnet_stats_rate_est * @requeues: number of requeues * @overlimits: number of enqueues over the limit */ -struct gnet_stats_queue -{ +struct gnet_stats_queue { __u32 qlen; __u32 backlog; __u32 drops; @@ -62,8 +58,7 @@ struct gnet_stats_queue * @interval: sampling period * @ewma_log: the log of measurement window weight */ -struct gnet_estimator -{ +struct gnet_estimator { signed char interval; unsigned char ewma_log; }; diff --git a/include/linux/if.h b/include/linux/if.h index 010a0d29..51fcf6a4 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -70,6 +70,7 @@ #define IFF_XMIT_DST_RELEASE 0x400 /* dev_hard_start_xmit() is allowed to * release skb->dst */ +#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */ #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 @@ -125,8 +126,7 @@ enum { * being very small might be worth keeping for clean configuration. */ -struct ifmap -{ +struct ifmap { unsigned long mem_start; unsigned long mem_end; unsigned short base_addr; @@ -136,8 +136,7 @@ struct ifmap /* 3 bytes spare */ }; -struct if_settings -{ +struct if_settings { unsigned int type; /* Type of physical device or protocol */ unsigned int size; /* Size of the data allocated by the caller */ union { @@ -161,8 +160,7 @@ struct if_settings * remainder may be interface specific. */ -struct ifreq -{ +struct ifreq { #define IFHWADDRLEN 6 union { @@ -211,11 +209,9 @@ struct ifreq * must know all networks accessible). */ -struct ifconf -{ +struct ifconf { int ifc_len; /* size of buffer */ - union - { + union { char *ifcu_buf; struct ifreq *ifcu_req; } ifc_ifcu; diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index 41b0193d..58b39f47 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -4,8 +4,7 @@ #include #include -struct ifaddrmsg -{ +struct ifaddrmsg { __u8 ifa_family; __u8 ifa_prefixlen; /* The prefix length */ __u8 ifa_flags; /* Flags */ @@ -20,8 +19,7 @@ struct ifaddrmsg * but for point-to-point IFA_ADDRESS is DESTINATION address, * local address is supplied in IFA_LOCAL attribute. */ -enum -{ +enum { IFA_UNSPEC, IFA_ADDRESS, IFA_LOCAL, @@ -47,8 +45,7 @@ enum #define IFA_F_TENTATIVE 0x40 #define IFA_F_PERMANENT 0x80 -struct ifa_cacheinfo -{ +struct ifa_cacheinfo { __u32 ifa_prefered; __u32 ifa_valid; __u32 cstamp; /* created timestamp, hundredths of seconds */ diff --git a/include/linux/if_addrlabel.h b/include/linux/if_addrlabel.h index 89571f65..54580c29 100644 --- a/include/linux/if_addrlabel.h +++ b/include/linux/if_addrlabel.h @@ -12,8 +12,7 @@ #include -struct ifaddrlblmsg -{ +struct ifaddrlblmsg { __u8 ifal_family; /* Address family */ __u8 __ifal_reserved; /* Reserved */ __u8 ifal_prefixlen; /* Prefix length */ @@ -22,8 +21,7 @@ struct ifaddrlblmsg __u32 ifal_seq; /* sequence number */ }; -enum -{ +enum { IFAL_ADDRESS = 1, IFAL_LABEL = 2, __IFAL_MAX diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index 57a8f38e..cafee458 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -133,8 +133,7 @@ struct arpreq_old { * This structure defines an ethernet arp header. */ -struct arphdr -{ +struct arphdr { __be16 ar_hrd; /* format of hardware address */ __be16 ar_pro; /* format of protocol address */ unsigned char ar_hln; /* length of hardware address */ diff --git a/include/linux/if_link.h b/include/linux/if_link.h index b0b9e8a6..cbefb3bc 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -5,8 +5,7 @@ #include /* The struct should be in sync with struct net_device_stats */ -struct rtnl_link_stats -{ +struct rtnl_link_stats { __u32 rx_packets; /* total packets received */ __u32 tx_packets; /* total packets transmitted */ __u32 rx_bytes; /* total bytes received */ @@ -39,8 +38,7 @@ struct rtnl_link_stats }; /* The struct should be in sync with struct ifmap */ -struct rtnl_link_ifmap -{ +struct rtnl_link_ifmap { __u64 mem_start; __u64 mem_end; __u64 base_addr; @@ -49,8 +47,7 @@ struct rtnl_link_ifmap __u8 port; }; -enum -{ +enum { IFLA_UNSPEC, IFLA_ADDRESS, IFLA_BROADCAST, @@ -121,8 +118,7 @@ enum */ /* Subtype attributes for IFLA_PROTINFO */ -enum -{ +enum { IFLA_INET6_UNSPEC, IFLA_INET6_FLAGS, /* link flags */ IFLA_INET6_CONF, /* sysctl parameters */ @@ -135,16 +131,14 @@ enum #define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) -struct ifla_cacheinfo -{ +struct ifla_cacheinfo { __u32 max_reasm_len; __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ __u32 reachable_time; __u32 retrans_time; }; -enum -{ +enum { IFLA_INFO_UNSPEC, IFLA_INFO_KIND, IFLA_INFO_DATA, @@ -156,8 +150,7 @@ enum /* VLAN section */ -enum -{ +enum { IFLA_VLAN_UNSPEC, IFLA_VLAN_ID, IFLA_VLAN_FLAGS, @@ -173,8 +166,7 @@ struct ifla_vlan_flags { __u32 mask; }; -enum -{ +enum { IFLA_VLAN_QOS_UNSPEC, IFLA_VLAN_QOS_MAPPING, __IFLA_VLAN_QOS_MAX @@ -182,10 +174,24 @@ enum #define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1) -struct ifla_vlan_qos_mapping -{ +struct ifla_vlan_qos_mapping { __u32 from; __u32 to; }; +/* MACVLAN section */ +enum { + IFLA_MACVLAN_UNSPEC, + IFLA_MACVLAN_MODE, + __IFLA_MACVLAN_MAX, +}; + +#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) + +enum macvlan_mode { + MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */ + MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */ + MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ +}; + #endif /* _LINUX_IF_LINK_H */ diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 3036cec1..6c8d1d1e 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h @@ -12,6 +12,10 @@ #define SIOCADDPRL (SIOCDEVPRIVATE + 5) #define SIOCDELPRL (SIOCDEVPRIVATE + 6) #define SIOCCHGPRL (SIOCDEVPRIVATE + 7) +#define SIOCGET6RD (SIOCDEVPRIVATE + 8) +#define SIOCADD6RD (SIOCDEVPRIVATE + 9) +#define SIOCDEL6RD (SIOCDEVPRIVATE + 10) +#define SIOCCHG6RD (SIOCDEVPRIVATE + 11) #define GRE_CSUM __cpu_to_be16(0x8000) #define GRE_ROUTING __cpu_to_be16(0x4000) @@ -22,8 +26,7 @@ #define GRE_FLAGS __cpu_to_be16(0x00F8) #define GRE_VERSION __cpu_to_be16(0x0007) -struct ip_tunnel_parm -{ +struct ip_tunnel_parm { char name[IFNAMSIZ]; int link; __be16 i_flags; @@ -48,8 +51,14 @@ struct ip_tunnel_prl { /* PRL flags */ #define PRL_DEFAULT 0x0001 -enum -{ +struct ip_tunnel_6rd { + struct in6_addr prefix; + __be32 relay_prefix; + __u16 prefixlen; + __u16 relay_prefixlen; +}; + +enum { IFLA_GRE_UNSPEC, IFLA_GRE_LINK, IFLA_GRE_IFLAGS, diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 2dc4a57d..329b3546 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -33,6 +33,7 @@ enum vlan_ioctl_cmds { enum vlan_flags { VLAN_FLAG_REORDER_HDR = 0x1, VLAN_FLAG_GVRP = 0x2, + VLAN_FLAG_LOOSE_BINDING = 0x4, }; enum vlan_name_types { diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h index 12c9de13..a7003b7a 100644 --- a/include/linux/neighbour.h +++ b/include/linux/neighbour.h @@ -4,8 +4,7 @@ #include #include -struct ndmsg -{ +struct ndmsg { __u8 ndm_family; __u8 ndm_pad1; __u16 ndm_pad2; @@ -15,8 +14,7 @@ struct ndmsg __u8 ndm_type; }; -enum -{ +enum { NDA_UNSPEC, NDA_DST, NDA_LLADDR, @@ -56,8 +54,7 @@ enum NUD_PERMANENT is also cannot be deleted by garbage collectors. */ -struct nda_cacheinfo -{ +struct nda_cacheinfo { __u32 ndm_confirmed; __u32 ndm_used; __u32 ndm_updated; @@ -89,8 +86,7 @@ struct nda_cacheinfo * device. ****/ -struct ndt_stats -{ +struct ndt_stats { __u64 ndts_allocs; __u64 ndts_destroys; __u64 ndts_hash_grows; @@ -124,15 +120,13 @@ enum { }; #define NDTPA_MAX (__NDTPA_MAX - 1) -struct ndtmsg -{ +struct ndtmsg { __u8 ndtm_family; __u8 ndtm_pad1; __u16 ndtm_pad2; }; -struct ndt_config -{ +struct ndt_config { __u16 ndtc_key_len; __u16 ndtc_entry_size; __u32 ndtc_entries; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 260f0109..9035dfaf 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -38,8 +38,7 @@ * with byte counters. */ -struct net_device_stats -{ +struct net_device_stats { unsigned long rx_packets; /* total packets received */ unsigned long tx_packets; /* total packets transmitted */ unsigned long rx_bytes; /* total bytes received */ diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 2794d971..ccb56410 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -6,8 +6,7 @@ #define XT_FUNCTION_MAXNAMELEN 30 #define XT_TABLE_MAXNAMELEN 32 -struct xt_entry_match -{ +struct xt_entry_match { union { struct { __u16 match_size; @@ -31,8 +30,7 @@ struct xt_entry_match unsigned char data[0]; }; -struct xt_entry_target -{ +struct xt_entry_target { union { struct { __u16 target_size; @@ -64,16 +62,14 @@ struct xt_entry_target }, \ } -struct xt_standard_target -{ +struct xt_standard_target { struct xt_entry_target target; int verdict; }; /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision * kernel supports, if >= revision. */ -struct xt_get_revision -{ +struct xt_get_revision { char name[XT_FUNCTION_MAXNAMELEN-1]; __u8 revision; @@ -90,8 +86,7 @@ struct xt_get_revision * ip6t_entry and arpt_entry. This sucks, and it is a hack. It will be my * personal pleasure to remove it -HW */ -struct _xt_align -{ +struct _xt_align { __u8 u8; __u16 u16; __u32 u32; @@ -109,14 +104,12 @@ struct _xt_align #define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) -struct xt_counters -{ +struct xt_counters { __u64 pcnt, bcnt; /* Packet and byte counters */ }; /* The argument to IPT_SO_ADD_COUNTERS. */ -struct xt_counters_info -{ +struct xt_counters_info { /* Which table. */ char name[XT_TABLE_MAXNAMELEN]; diff --git a/include/linux/netfilter/xt_tcpudp.h b/include/linux/netfilter/xt_tcpudp.h index a490a0bc..38aa7b39 100644 --- a/include/linux/netfilter/xt_tcpudp.h +++ b/include/linux/netfilter/xt_tcpudp.h @@ -4,8 +4,7 @@ #include /* TCP matching stuff */ -struct xt_tcp -{ +struct xt_tcp { __u16 spts[2]; /* Source port range. */ __u16 dpts[2]; /* Destination port range. */ __u8 option; /* TCP Option iff non-zero*/ @@ -22,8 +21,7 @@ struct xt_tcp #define XT_TCP_INV_MASK 0x0F /* All possible flags. */ /* UDP matching stuff */ -struct xt_udp -{ +struct xt_udp { __u16 spts[2]; /* Source port range. */ __u16 dpts[2]; /* Destination port range. */ __u8 invflags; /* Inverse flags */ diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index a9f21c9b..735f4b1b 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -70,8 +70,7 @@ struct ipt_ip { /* This structure defines each of the firewall rules. Consists of 3 parts which are 1) general IP header stuff 2) match specific stuff 3) the target to perform if the rule matches */ -struct ipt_entry -{ +struct ipt_entry { struct ipt_ip ip; /* Mark with fields that we care about. */ @@ -129,8 +128,7 @@ struct ipt_entry #define IPT_UDP_INV_MASK XT_UDP_INV_MASK /* ICMP matching stuff */ -struct ipt_icmp -{ +struct ipt_icmp { u_int8_t type; /* type to match */ u_int8_t code[2]; /* range of code */ u_int8_t invflags; /* Inverse flags */ @@ -140,8 +138,7 @@ struct ipt_icmp #define IPT_ICMP_INV 0x01 /* Invert the sense of type/code test */ /* The argument to IPT_SO_GET_INFO */ -struct ipt_getinfo -{ +struct ipt_getinfo { /* Which table: caller fills this in. */ char name[IPT_TABLE_MAXNAMELEN]; @@ -163,8 +160,7 @@ struct ipt_getinfo }; /* The argument to IPT_SO_SET_REPLACE. */ -struct ipt_replace -{ +struct ipt_replace { /* Which table. */ char name[IPT_TABLE_MAXNAMELEN]; @@ -198,8 +194,7 @@ struct ipt_replace #define ipt_counters_info xt_counters_info /* The argument to IPT_SO_GET_ENTRIES. */ -struct ipt_get_entries -{ +struct ipt_get_entries { /* Which table: user fills this in. */ char name[IPT_TABLE_MAXNAMELEN]; diff --git a/include/linux/netlink.h b/include/linux/netlink.h index ec780bbf..958b7f80 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -29,16 +29,14 @@ struct net; -struct sockaddr_nl -{ +struct sockaddr_nl { sa_family_t nl_family; /* AF_NETLINK */ unsigned short nl_pad; /* zero */ __u32 nl_pid; /* port ID */ __u32 nl_groups; /* multicast groups mask */ }; -struct nlmsghdr -{ +struct nlmsghdr { __u32 nlmsg_len; /* Length of message including header */ __u16 nlmsg_type; /* Message content */ __u16 nlmsg_flags; /* Additional flags */ @@ -94,8 +92,7 @@ struct nlmsghdr #define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */ -struct nlmsgerr -{ +struct nlmsgerr { int error; struct nlmsghdr msg; }; @@ -106,8 +103,7 @@ struct nlmsgerr #define NETLINK_BROADCAST_ERROR 4 #define NETLINK_NO_ENOBUFS 5 -struct nl_pktinfo -{ +struct nl_pktinfo { __u32 group; }; @@ -127,8 +123,7 @@ enum { * <-------------- nlattr->nla_len --------------> */ -struct nlattr -{ +struct nlattr { __u16 nla_len; __u16 nla_type; }; diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 3c842edf..7f6ba865 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -75,8 +75,7 @@ bits 9,10,11: redirect counter - redirect TTL. Loop avoidance #define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT)) /* Action attributes */ -enum -{ +enum { TCA_ACT_UNSPEC, TCA_ACT_KIND, TCA_ACT_OPTIONS, @@ -108,8 +107,7 @@ enum #define TC_ACT_JUMP 0x10000000 /* Action type identifiers*/ -enum -{ +enum { TCA_ID_UNSPEC=0, TCA_ID_POLICE=1, /* other actions go here */ @@ -118,8 +116,7 @@ enum #define TCA_ID_MAX __TCA_ID_MAX -struct tc_police -{ +struct tc_police { __u32 index; int action; #define TC_POLICE_UNSPEC TC_ACT_UNSPEC @@ -138,15 +135,13 @@ struct tc_police __u32 capab; }; -struct tcf_t -{ +struct tcf_t { __u64 install; __u64 lastuse; __u64 expires; }; -struct tc_cnt -{ +struct tc_cnt { int refcnt; int bindcnt; }; @@ -158,8 +153,7 @@ struct tc_cnt int refcnt; \ int bindcnt -enum -{ +enum { TCA_POLICE_UNSPEC, TCA_POLICE_TBF, TCA_POLICE_RATE, @@ -182,8 +176,7 @@ enum #define TC_U32_UNSPEC 0 #define TC_U32_ROOT (0xFFF00000) -enum -{ +enum { TCA_U32_UNSPEC, TCA_U32_CLASSID, TCA_U32_HASH, @@ -200,16 +193,14 @@ enum #define TCA_U32_MAX (__TCA_U32_MAX - 1) -struct tc_u32_key -{ +struct tc_u32_key { __be32 mask; __be32 val; int off; int offmask; }; -struct tc_u32_sel -{ +struct tc_u32_sel { unsigned char flags; unsigned char offshift; unsigned char nkeys; @@ -223,15 +214,13 @@ struct tc_u32_sel struct tc_u32_key keys[0]; }; -struct tc_u32_mark -{ +struct tc_u32_mark { __u32 val; __u32 mask; __u32 success; }; -struct tc_u32_pcnt -{ +struct tc_u32_pcnt { __u64 rcnt; __u64 rhit; __u64 kcnts[0]; @@ -249,8 +238,7 @@ struct tc_u32_pcnt /* RSVP filter */ -enum -{ +enum { TCA_RSVP_UNSPEC, TCA_RSVP_CLASSID, TCA_RSVP_DST, @@ -263,15 +251,13 @@ enum #define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 ) -struct tc_rsvp_gpi -{ +struct tc_rsvp_gpi { __u32 key; __u32 mask; int offset; }; -struct tc_rsvp_pinfo -{ +struct tc_rsvp_pinfo { struct tc_rsvp_gpi dpi; struct tc_rsvp_gpi spi; __u8 protocol; @@ -282,8 +268,7 @@ struct tc_rsvp_pinfo /* ROUTE filter */ -enum -{ +enum { TCA_ROUTE4_UNSPEC, TCA_ROUTE4_CLASSID, TCA_ROUTE4_TO, @@ -299,8 +284,7 @@ enum /* FW filter */ -enum -{ +enum { TCA_FW_UNSPEC, TCA_FW_CLASSID, TCA_FW_POLICE, @@ -314,8 +298,7 @@ enum /* TC index filter */ -enum -{ +enum { TCA_TCINDEX_UNSPEC, TCA_TCINDEX_HASH, TCA_TCINDEX_MASK, @@ -331,8 +314,7 @@ enum /* Flow filter */ -enum -{ +enum { FLOW_KEY_SRC, FLOW_KEY_DST, FLOW_KEY_PROTO, @@ -355,14 +337,12 @@ enum #define FLOW_KEY_MAX (__FLOW_KEY_MAX - 1) -enum -{ +enum { FLOW_MODE_MAP, FLOW_MODE_HASH, }; -enum -{ +enum { TCA_FLOW_UNSPEC, TCA_FLOW_KEYS, TCA_FLOW_MODE, @@ -383,8 +363,7 @@ enum /* Basic filter */ -enum -{ +enum { TCA_BASIC_UNSPEC, TCA_BASIC_CLASSID, TCA_BASIC_EMATCHES, @@ -398,8 +377,7 @@ enum /* Cgroup classifier */ -enum -{ +enum { TCA_CGROUP_UNSPEC, TCA_CGROUP_ACT, TCA_CGROUP_POLICE, @@ -411,14 +389,12 @@ enum /* Extended Matches */ -struct tcf_ematch_tree_hdr -{ +struct tcf_ematch_tree_hdr { __u16 nmatches; __u16 progid; }; -enum -{ +enum { TCA_EMATCH_TREE_UNSPEC, TCA_EMATCH_TREE_HDR, TCA_EMATCH_TREE_LIST, @@ -426,8 +402,7 @@ enum }; #define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1) -struct tcf_ematch_hdr -{ +struct tcf_ematch_hdr { __u16 matchid; __u16 kind; __u16 flags; @@ -457,8 +432,7 @@ struct tcf_ematch_hdr #define TCF_EM_REL_MASK 3 #define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK) -enum -{ +enum { TCF_LAYER_LINK, TCF_LAYER_NETWORK, TCF_LAYER_TRANSPORT, @@ -479,13 +453,11 @@ enum #define TCF_EM_VLAN 6 #define TCF_EM_MAX 6 -enum -{ +enum { TCF_EM_PROG_TC }; -enum -{ +enum { TCF_EM_OPND_EQ, TCF_EM_OPND_GT, TCF_EM_OPND_LT diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index d51a2b3e..2cfa4bc8 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -29,8 +29,7 @@ Particular schedulers may have also their private records. */ -struct tc_stats -{ +struct tc_stats { __u64 bytes; /* NUmber of enqueues bytes */ __u32 packets; /* Number of enqueued packets */ __u32 drops; /* Packets dropped because of lack of resources */ @@ -42,8 +41,7 @@ struct tc_stats __u32 backlog; }; -struct tc_estimator -{ +struct tc_estimator { signed char interval; unsigned char ewma_log; }; @@ -75,8 +73,7 @@ struct tc_estimator #define TC_H_ROOT (0xFFFFFFFFU) #define TC_H_INGRESS (0xFFFFFFF1U) -struct tc_ratespec -{ +struct tc_ratespec { unsigned char cell_log; unsigned char __reserved; unsigned short overhead; @@ -109,8 +106,7 @@ enum { /* FIFO section */ -struct tc_fifo_qopt -{ +struct tc_fifo_qopt { __u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */ }; @@ -119,8 +115,7 @@ struct tc_fifo_qopt #define TCQ_PRIO_BANDS 16 #define TCQ_MIN_PRIO_BANDS 2 -struct tc_prio_qopt -{ +struct tc_prio_qopt { int bands; /* Number of bands */ __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ }; @@ -134,8 +129,7 @@ struct tc_multiq_qopt { /* TBF section */ -struct tc_tbf_qopt -{ +struct tc_tbf_qopt { struct tc_ratespec rate; struct tc_ratespec peakrate; __u32 limit; @@ -143,8 +137,7 @@ struct tc_tbf_qopt __u32 mtu; }; -enum -{ +enum { TCA_TBF_UNSPEC, TCA_TBF_PARMS, TCA_TBF_RTAB, @@ -161,8 +154,7 @@ enum /* SFQ section */ -struct tc_sfq_qopt -{ +struct tc_sfq_qopt { unsigned quantum; /* Bytes per round allocated to flow */ int perturb_period; /* Period of hash perturbation */ __u32 limit; /* Maximal packets in queue */ @@ -170,8 +162,7 @@ struct tc_sfq_qopt unsigned flows; /* Maximal number of flows */ }; -struct tc_sfq_xstats -{ +struct tc_sfq_xstats { __s32 allot; }; @@ -186,8 +177,7 @@ struct tc_sfq_xstats /* RED section */ -enum -{ +enum { TCA_RED_UNSPEC, TCA_RED_PARMS, TCA_RED_STAB, @@ -196,8 +186,7 @@ enum #define TCA_RED_MAX (__TCA_RED_MAX - 1) -struct tc_red_qopt -{ +struct tc_red_qopt { __u32 limit; /* HARD maximal queue length (bytes) */ __u32 qth_min; /* Min average length threshold (bytes) */ __u32 qth_max; /* Max average length threshold (bytes) */ @@ -209,8 +198,7 @@ struct tc_red_qopt #define TC_RED_HARDDROP 2 }; -struct tc_red_xstats -{ +struct tc_red_xstats { __u32 early; /* Early drops */ __u32 pdrop; /* Drops due to queue limits */ __u32 other; /* Drops due to drop() calls */ @@ -221,8 +209,7 @@ struct tc_red_xstats #define MAX_DPs 16 -enum -{ +enum { TCA_GRED_UNSPEC, TCA_GRED_PARMS, TCA_GRED_STAB, @@ -232,8 +219,7 @@ enum #define TCA_GRED_MAX (__TCA_GRED_MAX - 1) -struct tc_gred_qopt -{ +struct tc_gred_qopt { __u32 limit; /* HARD maximal queue length (bytes) */ __u32 qth_min; /* Min average length threshold (bytes) */ __u32 qth_max; /* Max average length threshold (bytes) */ @@ -253,8 +239,7 @@ struct tc_gred_qopt }; /* gred setup */ -struct tc_gred_sopt -{ +struct tc_gred_sopt { __u32 DPs; __u32 def_DP; __u8 grio; @@ -267,8 +252,7 @@ struct tc_gred_sopt #define TC_HTB_MAXDEPTH 8 #define TC_HTB_PROTOVER 3 /* the same as HTB and TC's major */ -struct tc_htb_opt -{ +struct tc_htb_opt { struct tc_ratespec rate; struct tc_ratespec ceil; __u32 buffer; @@ -277,8 +261,7 @@ struct tc_htb_opt __u32 level; /* out only */ __u32 prio; }; -struct tc_htb_glob -{ +struct tc_htb_glob { __u32 version; /* to match HTB/TC */ __u32 rate2quantum; /* bps->quantum divisor */ __u32 defcls; /* default class number */ @@ -287,8 +270,7 @@ struct tc_htb_glob /* stats */ __u32 direct_pkts; /* count of non shapped packets */ }; -enum -{ +enum { TCA_HTB_UNSPEC, TCA_HTB_PARMS, TCA_HTB_INIT, @@ -299,8 +281,7 @@ enum #define TCA_HTB_MAX (__TCA_HTB_MAX - 1) -struct tc_htb_xstats -{ +struct tc_htb_xstats { __u32 lends; __u32 borrows; __u32 giants; /* too big packets (rate will not be accurate) */ @@ -310,28 +291,24 @@ struct tc_htb_xstats /* HFSC section */ -struct tc_hfsc_qopt -{ +struct tc_hfsc_qopt { __u16 defcls; /* default class */ }; -struct tc_service_curve -{ +struct tc_service_curve { __u32 m1; /* slope of the first segment in bps */ __u32 d; /* x-projection of the first segment in us */ __u32 m2; /* slope of the second segment in bps */ }; -struct tc_hfsc_stats -{ +struct tc_hfsc_stats { __u64 work; /* total work done */ __u64 rtwork; /* work done by real-time criteria */ __u32 period; /* current period */ __u32 level; /* class level in hierarchy */ }; -enum -{ +enum { TCA_HFSC_UNSPEC, TCA_HFSC_RSC, TCA_HFSC_FSC, @@ -348,8 +325,7 @@ enum #define TC_CBQ_MAXLEVEL 8 #define TC_CBQ_DEF_EWMA 5 -struct tc_cbq_lssopt -{ +struct tc_cbq_lssopt { unsigned char change; unsigned char flags; #define TCF_CBQ_LSS_BOUNDED 1 @@ -368,8 +344,7 @@ struct tc_cbq_lssopt __u32 avpkt; }; -struct tc_cbq_wrropt -{ +struct tc_cbq_wrropt { unsigned char flags; unsigned char priority; unsigned char cpriority; @@ -378,8 +353,7 @@ struct tc_cbq_wrropt __u32 weight; }; -struct tc_cbq_ovl -{ +struct tc_cbq_ovl { unsigned char strategy; #define TC_CBQ_OVL_CLASSIC 0 #define TC_CBQ_OVL_DELAY 1 @@ -391,30 +365,26 @@ struct tc_cbq_ovl __u32 penalty; }; -struct tc_cbq_police -{ +struct tc_cbq_police { unsigned char police; unsigned char __res1; unsigned short __res2; }; -struct tc_cbq_fopt -{ +struct tc_cbq_fopt { __u32 split; __u32 defmap; __u32 defchange; }; -struct tc_cbq_xstats -{ +struct tc_cbq_xstats { __u32 borrows; __u32 overactions; __s32 avgidle; __s32 undertime; }; -enum -{ +enum { TCA_CBQ_UNSPEC, TCA_CBQ_LSSOPT, TCA_CBQ_WRROPT, @@ -459,8 +429,7 @@ enum { /* Network emulator */ -enum -{ +enum { TCA_NETEM_UNSPEC, TCA_NETEM_CORR, TCA_NETEM_DELAY_DIST, @@ -471,8 +440,7 @@ enum #define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1) -struct tc_netem_qopt -{ +struct tc_netem_qopt { __u32 latency; /* added delay (us) */ __u32 limit; /* fifo limit (packets) */ __u32 loss; /* random packet loss (0=none ~0=100%) */ @@ -481,21 +449,18 @@ struct tc_netem_qopt __u32 jitter; /* random jitter in latency (us) */ }; -struct tc_netem_corr -{ +struct tc_netem_corr { __u32 delay_corr; /* delay correlation */ __u32 loss_corr; /* packet loss correlation */ __u32 dup_corr; /* duplicate correlation */ }; -struct tc_netem_reorder -{ +struct tc_netem_reorder { __u32 probability; __u32 correlation; }; -struct tc_netem_corrupt -{ +struct tc_netem_corrupt { __u32 probability; __u32 correlation; }; @@ -504,8 +469,7 @@ struct tc_netem_corrupt /* DRR */ -enum -{ +enum { TCA_DRR_UNSPEC, TCA_DRR_QUANTUM, __TCA_DRR_MAX @@ -513,8 +477,7 @@ enum #define TCA_DRR_MAX (__TCA_DRR_MAX - 1) -struct tc_drr_stats -{ +struct tc_drr_stats { __u32 deficit; }; diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index e8623807..5b46173f 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -127,8 +127,7 @@ enum { with attribute type. */ -struct rtattr -{ +struct rtattr { unsigned short rta_len; unsigned short rta_type; }; @@ -154,8 +153,7 @@ struct rtattr * Definitions used in routing table administration. ****/ -struct rtmsg -{ +struct rtmsg { unsigned char rtm_family; unsigned char rtm_dst_len; unsigned char rtm_src_len; @@ -171,8 +169,7 @@ struct rtmsg /* rtm_type */ -enum -{ +enum { RTN_UNSPEC, RTN_UNICAST, /* Gateway or direct route */ RTN_LOCAL, /* Accept locally */ @@ -230,8 +227,7 @@ enum could be assigned a value between UNIVERSE and LINK. */ -enum rt_scope_t -{ +enum rt_scope_t { RT_SCOPE_UNIVERSE=0, /* User defined values */ RT_SCOPE_SITE=200, @@ -249,8 +245,7 @@ enum rt_scope_t /* Reserved table identifiers */ -enum rt_class_t -{ +enum rt_class_t { RT_TABLE_UNSPEC=0, /* User defined values */ RT_TABLE_COMPAT=252, @@ -263,8 +258,7 @@ enum rt_class_t /* Routing message attributes */ -enum rtattr_type_t -{ +enum rtattr_type_t { RTA_UNSPEC, RTA_DST, RTA_SRC, @@ -298,8 +292,7 @@ enum rtattr_type_t * and rtt for different paths from multipath. */ -struct rtnexthop -{ +struct rtnexthop { unsigned short rtnh_len; unsigned char rtnh_flags; unsigned char rtnh_hops; @@ -325,8 +318,7 @@ struct rtnexthop /* RTM_CACHEINFO */ -struct rta_cacheinfo -{ +struct rta_cacheinfo { __u32 rta_clntref; __u32 rta_lastuse; __s32 rta_expires; @@ -341,8 +333,7 @@ struct rta_cacheinfo /* RTM_METRICS --- array of struct rtattr with types of RTAX_* */ -enum -{ +enum { RTAX_UNSPEC, #define RTAX_UNSPEC RTAX_UNSPEC RTAX_LOCK, @@ -381,8 +372,7 @@ enum #define RTAX_FEATURE_TIMESTAMP 0x00000004 #define RTAX_FEATURE_ALLFRAG 0x00000008 -struct rta_session -{ +struct rta_session { __u8 proto; __u8 pad1; __u16 pad2; @@ -407,8 +397,7 @@ struct rta_session * General form of address family dependent message. ****/ -struct rtgenmsg -{ +struct rtgenmsg { unsigned char rtgen_family; }; @@ -421,8 +410,7 @@ struct rtgenmsg * on network protocol. */ -struct ifinfomsg -{ +struct ifinfomsg { unsigned char ifi_family; unsigned char __ifi_pad; unsigned short ifi_type; /* ARPHRD_* */ @@ -435,8 +423,7 @@ struct ifinfomsg * prefix information ****/ -struct prefixmsg -{ +struct prefixmsg { unsigned char prefix_family; unsigned char prefix_pad1; unsigned short prefix_pad2; @@ -457,8 +444,7 @@ enum #define PREFIX_MAX (__PREFIX_MAX - 1) -struct prefix_cacheinfo -{ +struct prefix_cacheinfo { __u32 preferred_time; __u32 valid_time; }; @@ -468,8 +454,7 @@ struct prefix_cacheinfo * Traffic control messages. ****/ -struct tcmsg -{ +struct tcmsg { unsigned char tcm_family; unsigned char tcm__pad1; unsigned short tcm__pad2; @@ -479,8 +464,7 @@ struct tcmsg __u32 tcm_info; }; -enum -{ +enum { TCA_UNSPEC, TCA_KIND, TCA_OPTIONS, @@ -502,8 +486,7 @@ enum * Neighbor Discovery userland options ****/ -struct nduseroptmsg -{ +struct nduseroptmsg { unsigned char nduseropt_family; unsigned char nduseropt_pad1; unsigned short nduseropt_opts_len; /* Total length of options */ @@ -515,8 +498,7 @@ struct nduseroptmsg /* Followed by one or more ND options */ }; -enum -{ +enum { NDUSEROPT_UNSPEC, NDUSEROPT_SRCADDR, __NDUSEROPT_MAX @@ -596,8 +578,7 @@ enum rtnetlink_groups { #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) /* TC action piece */ -struct tcamsg -{ +struct tcamsg { unsigned char tca_family; unsigned char tca__pad1; unsigned short tca__pad2; diff --git a/include/linux/tc_act/tc_gact.h b/include/linux/tc_act/tc_gact.h index e895c0a3..f7bf94ee 100644 --- a/include/linux/tc_act/tc_gact.h +++ b/include/linux/tc_act/tc_gact.h @@ -5,14 +5,12 @@ #include #define TCA_ACT_GACT 5 -struct tc_gact -{ +struct tc_gact { tc_gen; }; -struct tc_gact_p -{ +struct tc_gact_p { #define PGACT_NONE 0 #define PGACT_NETRAND 1 #define PGACT_DETERM 2 @@ -22,8 +20,7 @@ struct tc_gact_p int paction; }; -enum -{ +enum { TCA_GACT_UNSPEC, TCA_GACT_TM, TCA_GACT_PARMS, diff --git a/include/linux/tc_act/tc_ipt.h b/include/linux/tc_act/tc_ipt.h index 4b6f7b6c..a2335563 100644 --- a/include/linux/tc_act/tc_ipt.h +++ b/include/linux/tc_act/tc_ipt.h @@ -5,8 +5,7 @@ #define TCA_ACT_IPT 6 -enum -{ +enum { TCA_IPT_UNSPEC, TCA_IPT_TABLE, TCA_IPT_HOOK, diff --git a/include/linux/tc_act/tc_mirred.h b/include/linux/tc_act/tc_mirred.h index 0a99ab60..7561750e 100644 --- a/include/linux/tc_act/tc_mirred.h +++ b/include/linux/tc_act/tc_mirred.h @@ -10,15 +10,13 @@ #define TCA_INGRESS_REDIR 3 /* packet redirect to INGRESS*/ #define TCA_INGRESS_MIRROR 4 /* mirror packet to INGRESS */ -struct tc_mirred -{ +struct tc_mirred { tc_gen; int eaction; /* one of IN/EGRESS_MIRROR/REDIR */ __u32 ifindex; /* ifindex of egress port */ }; -enum -{ +enum { TCA_MIRRED_UNSPEC, TCA_MIRRED_TM, TCA_MIRRED_PARMS, diff --git a/include/linux/tc_act/tc_nat.h b/include/linux/tc_act/tc_nat.h index e7cf31e8..6663aeba 100644 --- a/include/linux/tc_act/tc_nat.h +++ b/include/linux/tc_act/tc_nat.h @@ -6,8 +6,7 @@ #define TCA_ACT_NAT 9 -enum -{ +enum { TCA_NAT_UNSPEC, TCA_NAT_PARMS, TCA_NAT_TM, @@ -17,8 +16,7 @@ enum #define TCA_NAT_FLAG_EGRESS 1 -struct tc_nat -{ +struct tc_nat { tc_gen; __be32 old_addr; __be32 new_addr; diff --git a/include/linux/tc_act/tc_pedit.h b/include/linux/tc_act/tc_pedit.h index 54ce9064..716cfabc 100644 --- a/include/linux/tc_act/tc_pedit.h +++ b/include/linux/tc_act/tc_pedit.h @@ -6,8 +6,7 @@ #define TCA_ACT_PEDIT 7 -enum -{ +enum { TCA_PEDIT_UNSPEC, TCA_PEDIT_TM, TCA_PEDIT_PARMS, @@ -15,8 +14,7 @@ enum }; #define TCA_PEDIT_MAX (__TCA_PEDIT_MAX - 1) -struct tc_pedit_key -{ +struct tc_pedit_key { __u32 mask; /* AND */ __u32 val; /*XOR */ __u32 off; /*offset */ @@ -25,8 +23,7 @@ struct tc_pedit_key __u32 shift; }; -struct tc_pedit_sel -{ +struct tc_pedit_sel { tc_gen; unsigned char nkeys; unsigned char flags; diff --git a/include/linux/tc_act/tc_skbedit.h b/include/linux/tc_act/tc_skbedit.h index a14e461a..7a2e910a 100644 --- a/include/linux/tc_act/tc_skbedit.h +++ b/include/linux/tc_act/tc_skbedit.h @@ -26,6 +26,7 @@ #define SKBEDIT_F_PRIORITY 0x1 #define SKBEDIT_F_QUEUE_MAPPING 0x2 +#define SKBEDIT_F_MARK 0x4 struct tc_skbedit { tc_gen; @@ -37,6 +38,7 @@ enum { TCA_SKBEDIT_PARMS, TCA_SKBEDIT_PRIORITY, TCA_SKBEDIT_QUEUE_MAPPING, + TCA_SKBEDIT_MARK, __TCA_SKBEDIT_MAX }; #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1) diff --git a/include/linux/tc_ematch/tc_em_cmp.h b/include/linux/tc_ematch/tc_em_cmp.h index 38e7f7b2..f34bb1ba 100644 --- a/include/linux/tc_ematch/tc_em_cmp.h +++ b/include/linux/tc_ematch/tc_em_cmp.h @@ -4,8 +4,7 @@ #include #include -struct tcf_em_cmp -{ +struct tcf_em_cmp { __u32 val; __u32 mask; __u16 off; @@ -15,8 +14,7 @@ struct tcf_em_cmp __u8 opnd:4; }; -enum -{ +enum { TCF_EM_ALIGN_U8 = 1, TCF_EM_ALIGN_U16 = 2, TCF_EM_ALIGN_U32 = 4 diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index dcfb733f..0864206e 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h @@ -4,8 +4,7 @@ #include #include -enum -{ +enum { TCA_EM_META_UNSPEC, TCA_EM_META_HDR, TCA_EM_META_LVALUE, @@ -14,8 +13,7 @@ enum }; #define TCA_EM_META_MAX (__TCA_EM_META_MAX - 1) -struct tcf_meta_val -{ +struct tcf_meta_val { __u16 kind; __u8 shift; __u8 op; @@ -26,16 +24,14 @@ struct tcf_meta_val #define TCF_META_ID_MASK 0x7ff #define TCF_META_ID(kind) ((kind) & TCF_META_ID_MASK) -enum -{ +enum { TCF_META_TYPE_VAR, TCF_META_TYPE_INT, __TCF_META_TYPE_MAX }; #define TCF_META_TYPE_MAX (__TCF_META_TYPE_MAX - 1) -enum -{ +enum { TCF_META_ID_VALUE, TCF_META_ID_RANDOM, TCF_META_ID_LOADAVG_0, @@ -87,8 +83,7 @@ enum }; #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) -struct tcf_meta_hdr -{ +struct tcf_meta_hdr { struct tcf_meta_val left; struct tcf_meta_val right; }; diff --git a/include/linux/tc_ematch/tc_em_nbyte.h b/include/linux/tc_ematch/tc_em_nbyte.h index 9ed8c2e5..7172cfb9 100644 --- a/include/linux/tc_ematch/tc_em_nbyte.h +++ b/include/linux/tc_ematch/tc_em_nbyte.h @@ -4,8 +4,7 @@ #include #include -struct tcf_em_nbyte -{ +struct tcf_em_nbyte { __u16 off; __u16 len:12; __u8 layer:4; diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index a59bc4a9..9686820b 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -10,8 +10,7 @@ /* Structure to encapsulate addresses. I do not want to use * "standard" structure. My apologies. */ -typedef union -{ +typedef union { __be32 a4; __be32 a6[4]; } xfrm_address_t; @@ -20,8 +19,7 @@ typedef union * the state by (spi,daddr,ah/esp) or to store information about * spi, protocol and tunnel address on output. */ -struct xfrm_id -{ +struct xfrm_id { xfrm_address_t daddr; __be32 spi; __u8 proto; @@ -45,8 +43,7 @@ struct xfrm_sec_ctx { /* Selector, used as selector both on policy rules (SPD) and SAs. */ -struct xfrm_selector -{ +struct xfrm_selector { xfrm_address_t daddr; xfrm_address_t saddr; __be16 dport; @@ -63,8 +60,7 @@ struct xfrm_selector #define XFRM_INF (~(__u64)0) -struct xfrm_lifetime_cfg -{ +struct xfrm_lifetime_cfg { __u64 soft_byte_limit; __u64 hard_byte_limit; __u64 soft_packet_limit; @@ -75,16 +71,14 @@ struct xfrm_lifetime_cfg __u64 hard_use_expires_seconds; }; -struct xfrm_lifetime_cur -{ +struct xfrm_lifetime_cur { __u64 bytes; __u64 packets; __u64 add_time; __u64 use_time; }; -struct xfrm_replay_state -{ +struct xfrm_replay_state { __u32 oseq; __u32 seq; __u32 bitmap; @@ -96,6 +90,13 @@ struct xfrm_algo { char alg_key[0]; }; +struct xfrm_algo_auth { + char alg_name[64]; + unsigned int alg_key_len; /* in bits */ + unsigned int alg_trunc_len; /* in bits */ + char alg_key[0]; +}; + struct xfrm_algo_aead { char alg_name[64]; unsigned int alg_key_len; /* in bits */ @@ -109,16 +110,14 @@ struct xfrm_stats { __u32 integrity_failed; }; -enum -{ +enum { XFRM_POLICY_TYPE_MAIN = 0, XFRM_POLICY_TYPE_SUB = 1, XFRM_POLICY_TYPE_MAX = 2, XFRM_POLICY_TYPE_ANY = 255 }; -enum -{ +enum { XFRM_POLICY_IN = 0, XFRM_POLICY_OUT = 1, XFRM_POLICY_FWD = 2, @@ -126,8 +125,7 @@ enum XFRM_POLICY_MAX = 3 }; -enum -{ +enum { XFRM_SHARE_ANY, /* No limitations */ XFRM_SHARE_SESSION, /* For this session only */ XFRM_SHARE_USER, /* For this user only */ @@ -283,6 +281,7 @@ enum xfrm_attr_type_t { XFRMA_MIGRATE, XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */ XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */ + XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) From 2180b6b50bdc50e1a7740e5283930088da0bbae7 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 1 Dec 2009 01:21:39 +0000 Subject: [PATCH 29/59] iplink_vlan: add support for VLAN loose binding flag This patch adds support for the VLAN loose binding flag that is supported in net-next to iplink_vlan. commit 870970deb6cbea7a5d4881bdd717304d5284d315 Author: Patrick McHardy Date: Tue Dec 1 12:21:15 2009 +0100 iplink_vlan: add support for VLAN loose binding flag Signed-off-by: Patrick McHardy --- ip/iplink_vlan.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ip/iplink_vlan.c b/ip/iplink_vlan.c index 97244826..223feb31 100644 --- a/ip/iplink_vlan.c +++ b/ip/iplink_vlan.c @@ -27,6 +27,7 @@ static void explain(void) "VLANID := 0-4095\n" "FLAG-LIST := [ FLAG-LIST ] FLAG\n" "FLAG := [ reorder_hdr { on | off } ] [ gvrp { on | off } ]\n" + " [ loose_binding { on | off } ]\n" "QOS-MAP := [ QOS-MAP ] QOS-MAPPING\n" "QOS-MAPPING := FROM:TO\n" ); @@ -102,6 +103,15 @@ static int vlan_parse_opt(struct link_util *lu, int argc, char **argv, flags.flags &= ~VLAN_FLAG_GVRP; else return on_off("gvrp"); + } else if (matches(*argv, "loose_binding") == 0) { + NEXT_ARG(); + flags.mask |= VLAN_FLAG_LOOSE_BINDING; + if (strcmp(*argv, "on") == 0) + flags.flags |= VLAN_FLAG_LOOSE_BINDING; + else if (strcmp(*argv, "off") == 0) + flags.flags &= ~VLAN_FLAG_LOOSE_BINDING; + else + return on_off("loose_binding"); } else if (matches(*argv, "ingress-qos-map") == 0) { NEXT_ARG(); if (vlan_parse_qos_map(&argc, &argv, n, @@ -156,6 +166,7 @@ static void vlan_print_flags(FILE *fp, __u32 flags) } _PF(REORDER_HDR); _PF(GVRP); + _PF(LOOSE_BINDING); #undef _PF if (flags) fprintf(fp, "%x", flags); From e04dd30a38130a3d85065a747cc33274766a9cb6 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sat, 26 Dec 2009 11:12:43 -0800 Subject: [PATCH 30/59] skbedit: Add support to mark packets This adds support for setting the skb mark. Signed-off-by: Jamal Hadi Salim Signed-off-by: Alexander Duyck --- tc/m_skbedit.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c index 9044353d..5d1a96a8 100644 --- a/tc/m_skbedit.c +++ b/tc/m_skbedit.c @@ -31,10 +31,13 @@ static void explain(void) { - fprintf(stderr, "Usage: ... skbedit " - "queue_mapping QUEUE_MAPPING | priority PRIORITY \n" - "QUEUE_MAPPING = device transmit queue to use\n" - "PRIORITY = classID to assign to priority field\n"); + fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n" + "QM = queue_mapping QUEUE_MAPPING\n" + "PM = priority PRIORITY \n" + "MM = mark MARK \n" + "QUEUE_MAPPING = device transmit queue to use\n" + "PRIORITY = classID to assign to priority field\n" + "MARK = firewall mark to set\n"); } static void @@ -54,7 +57,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct rtattr *tail; unsigned int tmp; __u16 queue_mapping; - __u32 flags = 0, priority; + __u32 flags = 0, priority, mark; struct tc_skbedit sel = { 0 }; if (matches(*argv, "skbedit") != 0) @@ -80,6 +83,14 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, return -1; } ok++; + } else if (matches(*argv, "mark") == 0) { + flags |= SKBEDIT_F_MARK; + NEXT_ARG(); + if (get_tc_classid(&mark, *argv)) { + fprintf(stderr, "Illegal mark\n"); + return -1; + } + ok++; } else if (matches(*argv, "help") == 0) { usage(); } else { @@ -137,6 +148,9 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, if (flags & SKBEDIT_F_PRIORITY) addattr_l(n, MAX_MSG, TCA_SKBEDIT_PRIORITY, &priority, sizeof(priority)); + if (flags & SKBEDIT_F_MARK) + addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK, + &mark, sizeof(mark)); tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail; *argc_p = argc; @@ -150,6 +164,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) struct rtattr *tb[TCA_SKBEDIT_MAX + 1]; SPRINT_BUF(b1); __u32 *priority; + __u32 *mark; __u16 *queue_mapping; if (arg == NULL) @@ -174,6 +189,10 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) priority = RTA_DATA(tb[TCA_SKBEDIT_PRIORITY]); fprintf(f, " priority %s", sprint_tc_classid(*priority, b1)); } + if (tb[TCA_SKBEDIT_MARK] != NULL) { + mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]); + fprintf(f, " mark %d", *mark); + } if (show_stats) { if (tb[TCA_SKBEDIT_TM]) { From 85eae222d252546435bb5638b15d46ccfc9df32a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 3 Dec 2009 20:07:14 +0000 Subject: [PATCH 31/59] iprule: add oif classification support David Miller wrote: > From: Patrick McHardy > Date: Mon, 30 Nov 2009 19:00:14 +0100 > >> This patch contains iproute support for iprule oif classification >> for the send-to-self RFC I just sent out. > > Patrick, you need to submit a new version of this patch with > the FIB_RULE_* macro fixed, just like the kernel version got > fixed. Thanks for reminind me of this. New patch attached. commit 0fe5164cbaa1d65dda341075710be71bf1f32d10 Author: Patrick McHardy Date: Fri Dec 4 07:06:18 2009 +0100 iprule: add oif classification support Signed-off-by: Patrick McHardy --- ip/iprule.c | 13 +++++++++++-- man/man8/ip.8 | 10 +++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ip/iprule.c b/ip/iprule.c index 20be990b..7140375f 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -34,7 +34,7 @@ static void usage(void) { fprintf(stderr, "Usage: ip rule [ list | add | del | flush ] SELECTOR ACTION\n"); fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n"); - fprintf(stderr, " [ dev STRING ] [ pref NUMBER ]\n"); + fprintf(stderr, " [ iif STRING ] [ oif STRING ] [ pref NUMBER ]\n"); fprintf(stderr, "ACTION := [ table TABLE_ID ]\n"); fprintf(stderr, " [ prohibit | reject | unreachable ]\n"); fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n"); @@ -142,7 +142,13 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) if (tb[FRA_IFNAME]) { fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[FRA_IFNAME])); - if (r->rtm_flags & FIB_RULE_DEV_DETACHED) + if (r->rtm_flags & FIB_RULE_IIF_DETACHED) + fprintf(fp, "[detached] "); + } + + if (tb[FRA_OIFNAME]) { + fprintf(fp, "oif %s ", (char*)RTA_DATA(tb[FRA_OIFNAME])); + if (r->rtm_flags & FIB_RULE_OIF_DETACHED) fprintf(fp, "[detached] "); } @@ -307,6 +313,9 @@ static int iprule_modify(int cmd, int argc, char **argv) strcmp(*argv, "iif") == 0) { NEXT_ARG(); addattr_l(&req.n, sizeof(req), FRA_IFNAME, *argv, strlen(*argv)+1); + } else if (strcmp(*argv, "oif") == 0) { + NEXT_ARG(); + addattr_l(&req.n, sizeof(req), FRA_OIFNAME, *argv, strlen(*argv)+1); } else if (strcmp(*argv, "nat") == 0 || matches(*argv, "map-to") == 0) { NEXT_ARG(); diff --git a/man/man8/ip.8 b/man/man8/ip.8 index a8fccc41..fab337d9 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -240,7 +240,9 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" .IR TOS " ] [ " .B fwmark .IR FWMARK[/MASK] " ] [ " -.B dev +.B iif +.IR STRING " ] [ " +.B oif .IR STRING " ] [ " .B pref .IR NUMBER " ]" @@ -1935,6 +1937,12 @@ the rule only matches packets originating from this host. This means that you may create separate routing tables for forwarded and local packets and, hence, completely segregate them. +.TP +.BI oif " NAME" +select the outgoing device to match. The outgoing interface is only +available for packets originating from local sockets that are bound to +a device. + .TP .BI tos " TOS" .TP From a1f277943f86bd6974dfef9f59e5ee43eaeac300 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Thu, 3 Dec 2009 10:39:36 +0000 Subject: [PATCH 32/59] Add dadfailed option to ip command Fix support for IFA_F_DADFAILED and update ip.8 man page. Signed-off-by: Brian Haley --- ip/ipaddress.c | 8 ++++++-- man/man8/ip.8 | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ip/ipaddress.c b/ip/ipaddress.c index c638ca74..91c7b1ba 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -62,7 +62,7 @@ static void usage(void) iplink_usage(); } fprintf(stderr, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n"); - fprintf(stderr, " [ CONFFLAG-LIST]\n"); + fprintf(stderr, " [ CONFFLAG-LIST ]\n"); fprintf(stderr, " ip addr del IFADDR dev STRING\n"); fprintf(stderr, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n"); fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n"); @@ -72,7 +72,8 @@ static void usage(void) fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n"); fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n"); - fprintf(stderr, " tentative | deprecated | CONFFLAG-LIST ]\n"); + fprintf(stderr, " tentative | deprecated | dadfailed |\n"); + fprintf(stderr, " CONFFLAG-LIST ]\n"); fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"); fprintf(stderr, "CONFFLAG := [ home | nodad ]\n"); fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"); @@ -678,6 +679,9 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush) } else if (strcmp(*argv, "nodad") == 0) { filter.flags |= IFA_F_NODAD; filter.flagmask |= IFA_F_NODAD; + } else if (strcmp(*argv, "dadfailed") == 0) { + filter.flags |= IFA_F_DADFAILED; + filter.flagmask |= IFA_F_DADFAILED; } else if (strcmp(*argv, "label") == 0) { NEXT_ARG(); filter.label = *argv; diff --git a/man/man8/ip.8 b/man/man8/ip.8 index fab337d9..273be92b 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -97,7 +97,7 @@ ip \- show / manipulate routing, devices, policy routing and tunnels .ti -8 .IR FLAG " := " .RB "[ " permanent " | " dynamic " | " secondary " | " primary " | "\ -tentative " | " deprecated " ]" +tentative " | " deprecated " | " dadfailed " ]" .ti -8 .BR "ip addrlabel" " { " add " | " del " } " prefix @@ -1032,13 +1032,18 @@ addresses. .TP .B tentative -(IPv6 only) only list addresses which did not pass duplicate +(IPv6 only) only list addresses which have not yet passed duplicate address detection. .TP .B deprecated (IPv6 only) only list deprecated addresses. +.TP +.B dadfailed +(IPv6 only) only list addresses which have failed duplicate +address detection. + .TP .BR primary " and " secondary only list primary (or secondary) addresses. From d63a9b2b1e4e3eab0d0577d0a0f412d50be1e0a7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 26 Dec 2009 11:22:57 -0800 Subject: [PATCH 33/59] iproute2/iplink: add macvlan options for bridge mode Macvlan can now optionally support forwarding between its ports, if they are in "bridge" mode. This adds support for this option to "ip link add", "ip link set" and "ip -d link show". The default mode in the kernel is now "vepa" mode, meaning "virtual ethernet port aggregator". This mode is used together with the "hairpin" mode of an ethernet bridge that the parent of the macvlan device is connected to. All frames still get sent out to the external interface, but the adjacent bridge is able to send them back on the same wire in hairpin mode, so the macvlan ports are able to see each other, which the bridge can be configured to monitor and control traffic between all macvlan instances. Multicast traffic coming in from the external interface is checked for the source MAC address and only delivered to ports that have not yet seen it. In bridge mode, macvlan will send all multicast traffic to other interfaces that are also in bridge mode but not to those in vepa mode, which get them on the way back from the hairpin. The third supported mode is "private", which prevents communication between macvlans even if the adjacent bridge is in hairpin mode. This behavior is closer to the original implementation of macvlan but stricly maintains isolation. Signed-off-by: Arnd Bergmann --- ip/Makefile | 3 +- ip/iplink_macvlan.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 ip/iplink_macvlan.c diff --git a/ip/Makefile b/ip/Makefile index 51914e85..46a98361 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -2,7 +2,8 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o \ rtm_map.o iptunnel.o ip6tunnel.o tunnel.o ipneigh.o ipntable.o iplink.o \ ipmaddr.o ipmonitor.o ipmroute.o ipprefix.o \ ipxfrm.o xfrm_state.o xfrm_policy.o xfrm_monitor.o \ - iplink_vlan.o link_veth.o link_gre.o iplink_can.o + iplink_vlan.o link_veth.o link_gre.o iplink_can.o \ + iplink_macvlan.o RTMONOBJ=rtmon.o diff --git a/ip/iplink_macvlan.c b/ip/iplink_macvlan.c new file mode 100644 index 00000000..a3c78bd8 --- /dev/null +++ b/ip/iplink_macvlan.c @@ -0,0 +1,93 @@ +/* + * iplink_vlan.c VLAN device support + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Patrick McHardy + * Arnd Bergmann + */ + +#include +#include +#include +#include +#include + +#include "rt_names.h" +#include "utils.h" +#include "ip_common.h" + +static void explain(void) +{ + fprintf(stderr, + "Usage: ... macvlan mode { private | vepa | bridge }\n" + ); +} + +static int mode_arg(void) +{ + fprintf(stderr, "Error: argument of \"mode\" must be \"private\", " + "\"vepa\" or \"bridge\"\n"); + return -1; +} + +static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv, + struct nlmsghdr *n) +{ + while (argc > 0) { + if (matches(*argv, "mode") == 0) { + __u32 mode = 0; + NEXT_ARG(); + + if (strcmp(*argv, "private") == 0) + mode = MACVLAN_MODE_PRIVATE; + else if (strcmp(*argv, "vepa") == 0) + mode = MACVLAN_MODE_VEPA; + else if (strcmp(*argv, "bridge") == 0) + mode = MACVLAN_MODE_BRIDGE; + else + return mode_arg(); + + addattr32(n, 1024, IFLA_MACVLAN_MODE, mode); + } else if (matches(*argv, "help") == 0) { + explain(); + return -1; + } else { + fprintf(stderr, "macvlan: what is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--, argv++; + } + + return 0; +} + +static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) +{ + __u32 mode; + + if (!tb) + return; + + if (!tb[IFLA_MACVLAN_MODE] || + RTA_PAYLOAD(tb[IFLA_MACVLAN_MODE]) < sizeof(__u32)) + return; + + mode = *(__u32 *)RTA_DATA(tb[IFLA_VLAN_ID]); + fprintf(f, " mode %s ", + mode == MACVLAN_MODE_PRIVATE ? "private" + : mode == MACVLAN_MODE_VEPA ? "vepa" + : mode == MACVLAN_MODE_BRIDGE ? "bridge" + : "unknown"); +} + +struct link_util macvlan_link_util = { + .id = "macvlan", + .maxattr = IFLA_MACVLAN_MAX, + .parse_opt = macvlan_parse_opt, + .print_opt = macvlan_print_opt, +}; From 73152614bcab505198f443d3f79fb090ba458e51 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sat, 26 Dec 2009 14:52:36 -0500 Subject: [PATCH 34/59] tc: respect LDFLAGS for %.so targets Since there aren't any targets that currently use this pattern rule, this is more of a proactive fix. Signed-off-by: Mike Frysinger --- tc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/Makefile b/tc/Makefile index f3dd2b76..0b5d7d3e 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -87,7 +87,7 @@ YACC := bison LEX := flex %.so: %.c - $(CC) $(CFLAGS) -shared -fpic $< -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) -shared -fpic $< -o $@ all: libtc.a tc $(TCSO) From 14743a78eb774d61fd952c4a4856346ced79b9fb Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Fri, 1 Jan 2010 23:20:30 +0100 Subject: [PATCH 35/59] iproute2: avoid using bashisms in configure script. "function foo" should be "foo()" to work when sh is not bash. Signed-off-by: Andreas Henriksson --- configure | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure b/configure index a903bb0c..92a0b484 100755 --- a/configure +++ b/configure @@ -3,7 +3,7 @@ # INCLUDE=${1:-"$PWD/include"} -function check_atm +check_atm() { cat >/tmp/atmtest.c < @@ -24,7 +24,7 @@ fi rm -f /tmp/atmtest.c /tmp/atmtest } -function check_xt +check_xt() { #check if we have xtables from iptables >= 1.4.5. cat >/tmp/ipttest.c < /dev/null @@ -94,7 +94,7 @@ fi rm -f /tmp/ipttest.c /tmp/ipttest } -function check_xt_old_internal_h +check_xt_old_internal_h() { # bail if previous XT checks has already succeded. if grep TC_CONFIG_XT Config > /dev/null @@ -134,7 +134,7 @@ fi rm -f /tmp/ipttest.c /tmp/ipttest } -function check_ipt +check_ipt() { if ! grep TC_CONFIG_XT Config > /dev/null then From 15bb82c6fb9ae401f48eb7f03179ee6669496bf0 Mon Sep 17 00:00:00 2001 From: Alex Badea Date: Mon, 11 Jan 2010 17:23:41 +0200 Subject: [PATCH 36/59] ip xfrm state: parse and print "icmp" and "af-unspec" flags Convert to/from XFRM_STATE_ICMP and XFRM_STATE_AF_UNSPEC state flags. Signed-off-by: Alex Badea --- ip/ipxfrm.c | 2 ++ ip/xfrm_state.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index 18250de8..7dc36f36 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -780,6 +780,8 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo, XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_DECAP_DSCP, "decap-dscp"); XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_NOPMTUDISC, "nopmtudisc"); XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_WILDRECV, "wildrecv"); + XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_ICMP, "icmp"); + XFRM_FLAG_PRINT(fp, flags, XFRM_STATE_AF_UNSPEC, "af-unspec"); if (flags) fprintf(fp, "%x", flags); } diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index b1e3f220..32238ab7 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -83,7 +83,7 @@ static void usage(void) //fprintf(stderr, "REQID - number(default=0)\n"); fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); - fprintf(stderr, "FLAG := [ noecn | decap-dscp | nopmtudisc | wildrecv ]\n"); + fprintf(stderr, "FLAG := [ noecn | decap-dscp | nopmtudisc | wildrecv | icmp | af-unspec ]\n"); fprintf(stderr, "ENCAP := ENCAP-TYPE SPORT DPORT OADDR\n"); fprintf(stderr, "ENCAP-TYPE := espinudp | espinudp-nonike\n"); @@ -210,6 +210,10 @@ static int xfrm_state_flag_parse(__u8 *flags, int *argcp, char ***argvp) *flags |= XFRM_STATE_NOPMTUDISC; else if (strcmp(*argv, "wildrecv") == 0) *flags |= XFRM_STATE_WILDRECV; + else if (strcmp(*argv, "icmp") == 0) + *flags |= XFRM_STATE_ICMP; + else if (strcmp(*argv, "af-unspec") == 0) + *flags |= XFRM_STATE_AF_UNSPEC; else { PREV_ARG(); /* back track */ break; From e6e0b60f2a3d2720d4d9d6d0a50e3b48deea45e4 Mon Sep 17 00:00:00 2001 From: Alex Badea Date: Mon, 11 Jan 2010 17:24:04 +0200 Subject: [PATCH 37/59] ip xfrm policy: allow different tmpl family Allow tmpl IP addresses to have a different family than selector addresses. This is useful in conjunction with XFRM_STATE_AF_UNSPEC. Signed-off-by: Alex Badea --- ip/xfrm_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index 11116e5f..27884773 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -201,10 +201,10 @@ static int xfrm_tmpl_parse(struct xfrm_user_tmpl *tmpl, break; } idp = *argv; + preferred_family = AF_UNSPEC; xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family, 0, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = tmpl->family; + preferred_family = tmpl->family; } if (!NEXT_ARG_OK()) From 60de6507bb94f8d94b663c30847ad63655c7c30a Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 12 Jan 2010 21:39:12 +0100 Subject: [PATCH 38/59] tc: man: add limit parameter to tc-sfq man page Signed-off-by: Florian Westphal --- man/man8/tc-sfq.8 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man/man8/tc-sfq.8 b/man/man8/tc-sfq.8 index 337c7950..8f2b4333 100644 --- a/man/man8/tc-sfq.8 +++ b/man/man8/tc-sfq.8 @@ -51,6 +51,9 @@ on the fullest bucket, thus maintaining fairness. .SH PARAMETERS .TP +limit +Upper limit of the SFQ. Can be used to reduce the default length of 128 packets. +.TP perturb Interval in seconds for queue algorithm perturbation. Defaults to 0, which means that no perturbation occurs. Do not set too low for each perturbation may cause some packet From 9e318455a34bd76ab8b630d9133df830c0112200 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 12 Jan 2010 21:43:19 +0100 Subject: [PATCH 39/59] tc: man: SO_PRIORITY is described in socket documentation, not tc one fix up reference: there is no tc(7) man page. Signed-off-by: Florian Westphal --- man/man8/tc-prio.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man8/tc-prio.8 b/man/man8/tc-prio.8 index 780bcd5a..1625fccc 100644 --- a/man/man8/tc-prio.8 +++ b/man/man8/tc-prio.8 @@ -50,7 +50,7 @@ be enqueued. From userspace A process with sufficient privileges can encode the destination class directly with SO_PRIORITY, see -.BR tc(7). +.BR socket(7). .TP with a tc filter A tc filter attached to the root qdisc can point traffic directly to a class From ddf216c8631195549dbf84e4ebe3da1d77b45ce0 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 12 Jan 2010 21:44:29 +0100 Subject: [PATCH 40/59] tc: red, gred, tbf: more helpful error messages $ tc qdisc add dev eth1 root tbf RTNETLINK answers: Invalid argument $ tc qdisc add dev eth1 root red RTNETLINK answers: Invalid argument with patch: $ tc qdisc add dev eth1 root red Required parameter (min, max, burst, limit, avpkt) is missing $ tc qdisc add dev eth1 root tbf Usage: ... tbf limit BYTES burst BYTES[/BYTES] rate KBPS ... Signed-off-by: Florian Westphal --- tc/q_gred.c | 5 +---- tc/q_red.c | 14 +------------- tc/q_tbf.c | 6 ++++-- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/tc/q_gred.c b/tc/q_gred.c index ecef42e9..ab26801d 100644 --- a/tc/q_gred.c +++ b/tc/q_gred.c @@ -215,16 +215,13 @@ static int gred_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct n argc--; argv++; } - if (!ok) - return 0; - if (rate == 0) get_rate(&rate, "10Mbit"); if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt || (opt.DP<0)) { fprintf(stderr, "Required parameter (min, max, burst, limit, " - "avpket, DP) is missing\n"); + "avpkt, DP) is missing\n"); return -1; } diff --git a/tc/q_red.c b/tc/q_red.c index 6f93b26a..3ba6bc74 100644 --- a/tc/q_red.c +++ b/tc/q_red.c @@ -35,7 +35,6 @@ static void explain(void) static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { - int ok=0; struct tc_red_qopt opt; unsigned burst = 0; unsigned avpkt = 0; @@ -55,52 +54,44 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl fprintf(stderr, "Illegal \"limit\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "min") == 0) { NEXT_ARG(); if (get_size(&opt.qth_min, *argv)) { fprintf(stderr, "Illegal \"min\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "max") == 0) { NEXT_ARG(); if (get_size(&opt.qth_max, *argv)) { fprintf(stderr, "Illegal \"max\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "burst") == 0) { NEXT_ARG(); if (get_unsigned(&burst, *argv, 0)) { fprintf(stderr, "Illegal \"burst\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "avpkt") == 0) { NEXT_ARG(); if (get_size(&avpkt, *argv)) { fprintf(stderr, "Illegal \"avpkt\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "probability") == 0) { NEXT_ARG(); if (sscanf(*argv, "%lg", &probability) != 1) { fprintf(stderr, "Illegal \"probability\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "bandwidth") == 0) { NEXT_ARG(); if (get_rate(&rate, *argv)) { fprintf(stderr, "Illegal \"bandwidth\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "ecn") == 0) { ecn_ok = 1; - ok++; } else if (strcmp(*argv, "help") == 0) { explain(); return -1; @@ -112,14 +103,11 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl argc--; argv++; } - if (!ok) - return 0; - if (rate == 0) get_rate(&rate, "10Mbit"); if (!opt.qth_min || !opt.qth_max || !burst || !opt.limit || !avpkt) { - fprintf(stderr, "Required parameter (min, max, burst, limit, avpket) is missing\n"); + fprintf(stderr, "Required parameter (min, max, burst, limit, avpkt) is missing\n"); return -1; } diff --git a/tc/q_tbf.c b/tc/q_tbf.c index dbf95863..06ccda31 100644 --- a/tc/q_tbf.c +++ b/tc/q_tbf.c @@ -158,8 +158,10 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl argc--; argv++; } - if (!ok) - return 0; + if (!ok) { + explain(); + return -1; + } if (opt.rate.rate == 0 || !buffer) { fprintf(stderr, "Both \"rate\" and \"burst\" are required.\n"); From 8d8de1139c95d79bc1b5ac1ec301a30ef5e6ee50 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 12 Jan 2010 21:45:01 +0100 Subject: [PATCH 41/59] tc: remove stale code remove unused #define and "ok" statements. Signed-off-by: Florian Westphal --- tc/f_fw.c | 2 -- tc/f_route.c | 2 -- tc/f_rsvp.c | 2 -- tc/f_tcindex.c | 4 ---- tc/f_u32.c | 2 -- tc/q_atm.c | 2 -- tc/q_cbq.c | 3 +-- tc/q_drr.c | 1 - tc/q_dsmark.c | 3 --- tc/q_fifo.c | 2 -- tc/q_gred.c | 2 -- tc/q_htb.c | 2 -- tc/q_ingress.c | 2 -- tc/q_multiq.c | 2 -- tc/q_netem.c | 2 -- tc/q_prio.c | 4 ---- tc/q_red.c | 2 -- tc/q_rr.c | 3 --- tc/q_sfq.c | 2 -- tc/q_tbf.c | 2 -- 20 files changed, 1 insertion(+), 45 deletions(-) diff --git a/tc/f_fw.c b/tc/f_fw.c index cc8ea2d8..219b404f 100644 --- a/tc/f_fw.c +++ b/tc/f_fw.c @@ -31,8 +31,6 @@ static void explain(void) fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n"); } -#define usage() return(-1) - static int fw_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { struct tc_police tp; diff --git a/tc/f_route.c b/tc/f_route.c index 67dd49c0..eccf924b 100644 --- a/tc/f_route.c +++ b/tc/f_route.c @@ -34,8 +34,6 @@ static void explain(void) fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n"); } -#define usage() return(-1) - static int route_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { struct tc_police tp; diff --git a/tc/f_rsvp.c b/tc/f_rsvp.c index 7e1e6d92..808310df 100644 --- a/tc/f_rsvp.c +++ b/tc/f_rsvp.c @@ -37,8 +37,6 @@ static void explain(void) fprintf(stderr, "\nNOTE: CLASSID is parsed as hexadecimal input.\n"); } -#define usage() return(-1) - int get_addr_and_pi(int *argc_p, char ***argv_p, inet_prefix * addr, struct tc_rsvp_pinfo *pinfo, int dir, int family) { diff --git a/tc/f_tcindex.c b/tc/f_tcindex.c index 39ac75ad..cb6f854c 100644 --- a/tc/f_tcindex.c +++ b/tc/f_tcindex.c @@ -24,10 +24,6 @@ static void explain(void) "[ police POLICE_SPEC ]\n"); } - -#define usage() return(-1) - - static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/f_u32.c b/tc/f_u32.c index cb3f67ea..4f5f74e4 100644 --- a/tc/f_u32.c +++ b/tc/f_u32.c @@ -45,8 +45,6 @@ static void explain(void) fprintf(stderr, "\nNOTE: CLASSID is parsed at hexadecimal input.\n"); } -#define usage() return(-1) - int get_u32_handle(__u32 *handle, const char *str) { __u32 htid=0, hash=0, nodeid=0; diff --git a/tc/q_atm.c b/tc/q_atm.c index 4c8dc0b8..eec0d776 100644 --- a/tc/q_atm.c +++ b/tc/q_atm.c @@ -26,8 +26,6 @@ #define MAX_HDR_LEN 64 -#define usage() return(-1) - static int atm_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_cbq.c b/tc/q_cbq.c index c99dc3b6..3c5e72c1 100644 --- a/tc/q_cbq.c +++ b/tc/q_cbq.c @@ -46,7 +46,6 @@ static void explain1(char *arg) fprintf(stderr, "Illegal \"%s\"\n", arg); } -#define usage() return(-1) static int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { @@ -319,7 +318,7 @@ static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str NEXT_ARG(); if (get_tc_classid(&fopt.split, *argv)) { fprintf(stderr, "Invalid split node ID.\n"); - usage(); + return -1; } fopt_ok++; } else if (matches(*argv, "defmap") == 0) { diff --git a/tc/q_drr.c b/tc/q_drr.c index 7d2d8741..81de44d9 100644 --- a/tc/q_drr.c +++ b/tc/q_drr.c @@ -33,7 +33,6 @@ static void explain2(void) fprintf(stderr, "Usage: ... drr quantum SIZE\n"); } -#define usage() return(-1) static int drr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_dsmark.c b/tc/q_dsmark.c index cdb5bf2f..cfbb3351 100644 --- a/tc/q_dsmark.c +++ b/tc/q_dsmark.c @@ -19,9 +19,6 @@ #include "tc_util.h" -#define usage() return(-1) - - static void explain(void) { fprintf(stderr,"Usage: dsmark indices INDICES [ default_index " diff --git a/tc/q_fifo.c b/tc/q_fifo.c index 9f3b3eb2..f561752d 100644 --- a/tc/q_fifo.c +++ b/tc/q_fifo.c @@ -28,8 +28,6 @@ static void explain(void) fprintf(stderr, "Usage: ... [p|b]fifo [ limit NUMBER ]\n"); } -#define usage() return(-1) - static int fifo_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { int ok=0; diff --git a/tc/q_gred.c b/tc/q_gred.c index ab26801d..df4aa3d8 100644 --- a/tc/q_gred.c +++ b/tc/q_gred.c @@ -46,8 +46,6 @@ static void explain(void) "[grio]\n"); } -#define usage() return(-1) - static int init_gred(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_htb.c b/tc/q_htb.c index c69e350d..caa47c26 100644 --- a/tc/q_htb.c +++ b/tc/q_htb.c @@ -58,8 +58,6 @@ static void explain1(char *arg) } -#define usage() return(-1) - static int htb_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { struct tc_htb_glob opt; diff --git a/tc/q_ingress.c b/tc/q_ingress.c index 71fbd493..ba58e722 100644 --- a/tc/q_ingress.c +++ b/tc/q_ingress.c @@ -32,8 +32,6 @@ static void explain(void) fprintf(stderr, "Usage: ... ingress \n"); } -#define usage() return(-1) - static int ingress_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_multiq.c b/tc/q_multiq.c index 306e170d..fce5e449 100644 --- a/tc/q_multiq.c +++ b/tc/q_multiq.c @@ -41,8 +41,6 @@ static void explain(void) fprintf(stderr, "Usage: ... multiq [help]\n"); } -#define usage() return(-1) - static int multiq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { diff --git a/tc/q_netem.c b/tc/q_netem.c index 33b3d2a4..6aaaded9 100644 --- a/tc/q_netem.c +++ b/tc/q_netem.c @@ -42,8 +42,6 @@ static void explain1(const char *arg) fprintf(stderr, "Illegal \"%s\"\n", arg); } -#define usage() return(-1) - /* Upper bound on size of distribution * really (TCA_BUF_MAX - other headers) / sizeof (__s16) */ diff --git a/tc/q_prio.c b/tc/q_prio.c index 31a37cd8..2f54d550 100644 --- a/tc/q_prio.c +++ b/tc/q_prio.c @@ -28,11 +28,8 @@ static void explain(void) fprintf(stderr, "Usage: ... prio bands NUMBER priomap P1 P2...[multiqueue]\n"); } -#define usage() return(-1) - static int prio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { - int ok=0; int pmap_mode = 0; int idx = 0; struct tc_prio_qopt opt={3,{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }}; @@ -48,7 +45,6 @@ static int prio_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct n fprintf(stderr, "Illegal \"bands\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "priomap") == 0) { if (pmap_mode) { fprintf(stderr, "Error: duplicate priomap\n"); diff --git a/tc/q_red.c b/tc/q_red.c index 3ba6bc74..4b1b8893 100644 --- a/tc/q_red.c +++ b/tc/q_red.c @@ -31,8 +31,6 @@ static void explain(void) fprintf(stderr, " probability PROBABILITY bandwidth KBPS [ ecn ]\n"); } -#define usage() return(-1) - static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { struct tc_red_qopt opt; diff --git a/tc/q_rr.c b/tc/q_rr.c index 9bb8c7de..1ff3ac96 100644 --- a/tc/q_rr.c +++ b/tc/q_rr.c @@ -28,11 +28,9 @@ static void explain(void) fprintf(stderr, "Usage: ... rr bands NUMBER priomap P1 P2... [multiqueue]\n"); } -#define usage() return(-1) static int rr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { - int ok = 0; int pmap_mode = 0; int idx = 0; struct tc_prio_qopt opt={3,{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }}; @@ -48,7 +46,6 @@ static int rr_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlm fprintf(stderr, "Illegal \"bands\"\n"); return -1; } - ok++; } else if (strcmp(*argv, "priomap") == 0) { if (pmap_mode) { fprintf(stderr, "Error: duplicate priomap\n"); diff --git a/tc/q_sfq.c b/tc/q_sfq.c index ce4dade8..71a3c9ac 100644 --- a/tc/q_sfq.c +++ b/tc/q_sfq.c @@ -28,8 +28,6 @@ static void explain(void) fprintf(stderr, "Usage: ... sfq [ limit NUMBER ] [ perturb SECS ] [ quantum BYTES ]\n"); } -#define usage() return(-1) - static int sfq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { int ok=0; diff --git a/tc/q_tbf.c b/tc/q_tbf.c index 06ccda31..dc556fe0 100644 --- a/tc/q_tbf.c +++ b/tc/q_tbf.c @@ -36,8 +36,6 @@ static void explain1(char *arg) } -#define usage() return(-1) - static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) { int ok=0; From 5080db330ec15be7a1892f49949effd807a996fe Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 18 Jan 2010 23:54:02 +0100 Subject: [PATCH 42/59] tc: man: add man page for drr scheduler With help from Patrick McHardy. Signed-off-by: Florian Westphal --- man/man8/tc-drr.8 | 94 +++++++++++++++++++++++++++++++++++++++++++++++ man/man8/tc.8 | 1 + 2 files changed, 95 insertions(+) create mode 100644 man/man8/tc-drr.8 diff --git a/man/man8/tc-drr.8 b/man/man8/tc-drr.8 new file mode 100644 index 00000000..16a8ec0d --- /dev/null +++ b/man/man8/tc-drr.8 @@ -0,0 +1,94 @@ +.TH TC 8 "January 2010" "iproute2" "Linux" +.SH NAME +drr \- deficit round robin scheduler +.SH SYNOPSIS +.B tc qdisc ... add drr +.B [ quantum +bytes +.B ] + +.SH DESCRIPTION + +The Deficit Round Robin Scheduler is a classful queuing discipline as +a more flexible replacement for Stochastic Fairness Queuing. + +Unlike SFQ, there are no built-in queues \-\- you need to add classes +and then set up filters to classify packets accordingly. +This can be useful e.g. for using RED qdiscs with different settings for particular +traffic. There is no default class \-\- if a packet cannot be classified, +it is dropped. + +.SH ALGORITHM +Each class is assigned a deficit counter, initialized to +.B quantum. + +DRR maintains an (internal) ''active'' list of classes whose qdiscs are +non-empty. This list is used for dequeuing. A packet is dequeued from +the class at the head of the list if the packet size is smaller or equal +to the deficit counter. If the counter is too small, it is increased by +.B quantum +and the scheduler moves on to the next class in the active list. + + +.SH PARAMETERS +.TP +quantum +Amount of bytes a flow is allowed to dequeue before the scheduler moves to +the next class. Defaults to the MTU of the interface. The minimum value is 1. + +.SH EXAMPLE & USAGE + +To attach to device eth0, using the interface MTU as its quantum: +.P +# tc qdisc add dev eth0 handle 1 root drr +.P +Adding two classes: +.P +# tc class add dev eth0 parent 1: classid 1:1 drr +# tc class add dev eth0 parent 1: classid 1:2 drr +.P +You also need to add at least one filter to classify packets. +.P +# tc filter add dev eth0 protocol .. classid 1:1 +.P + +Like SFQ, DRR is only useful when it owns the queue \-\- it is a pure scheduler and does +not delay packets. Attaching non-work-conserving qdiscs like tbf to it does not make +sense \-\- other qdiscs in the active list will also become inactive until the dequeue +operation succeeds. Embed DRR within another qdisc like HTB or HFSC to ensure it owns the queue. +.P +You can mimic SFQ behavior by assigning packets to the attached classes using the +flow filter: + +.B tc qdisc add dev .. drr + +.B for i in .. 1024;do +.br +.B \ttc class add dev .. classid $handle:$(print %x $i) +.br +.B \ttc qdisc add dev .. fifo limit 16 +.br +.B done + +.B tc filter add .. protocol ip .. $handle flow hash keys src,dst,proto,proto-src,proto-dst divisor 1024 perturb 10 + + +.SH SOURCE +.TP +o +M. Shreedhar and George Varghese "Efficient Fair +Queuing using Deficit Round Robin", Proc. SIGCOMM 95. + +.SH NOTES + +This implementation does not drop packets from the longest queue on overrun, +as limits are handled by the individual child qdiscs. + +.SH SEE ALSO +.BR tc (8), +.BR tc-htb (8), +.BR tc-sfq (8) + +.SH AUTHOR +sched_drr was written by Patrick McHardy. + diff --git a/man/man8/tc.8 b/man/man8/tc.8 index 8c0880fa..e17ce68b 100644 --- a/man/man8/tc.8 +++ b/man/man8/tc.8 @@ -367,6 +367,7 @@ print rates in IEC units (ie. 1K = 1024). was written by Alexey N. Kuznetsov and added in Linux 2.2. .SH SEE ALSO .BR tc-cbq (8), +.BR tc-drr (8), .BR tc-htb (8), .BR tc-sfq (8), .BR tc-red (8), From a982e10a52407ca81b1c9aaec93871ec5b8bdb22 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 5 Feb 2010 12:02:38 -0800 Subject: [PATCH 43/59] iproute2-100205 --- include/SNAPSHOT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index 4696bfe8..0da650b4 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "091226"; +static const char SNAPSHOT[] = "100205"; From 63a0f20ac1fb2b98b6e68531b67ad83f09bbd272 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson Date: Tue, 9 Feb 2010 10:58:51 -0800 Subject: [PATCH 44/59] iproute2: drop equalize support Currently you can configure "equalize" and it looks all fine and dandy. The kernel has the interface defined, but apparently there's never actually been any implementation for it (only a never merged patch in the 2.4 era). I'm suggesting to drop the code to give any potential users of this feature the benefit of receiving a proper error message. I see it unlikely that this will be implemented in the near future, but if it ever happens reviving the iproute2 side should be as easy as git revert this patch. For more details see http://bugs.debian.org/149897 --- doc/ip-cref.tex | 8 -------- ip/iproute.c | 10 +--------- man/man8/ip.8 | 12 ------------ 3 files changed, 1 insertion(+), 29 deletions(-) diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex index 6ea44025..7bb562e1 100644 --- a/doc/ip-cref.tex +++ b/doc/ip-cref.tex @@ -1390,14 +1390,6 @@ database. even if it does not match any interface prefix. One application of this option may be found in~\cite{IP-TUNNELS}. -\item \verb|equalize| - ---- allow packet by packet randomization on multipath routes. -Without this modifier, the route will be frozen to one selected -nexthop, so that load splitting will only occur on per-flow base. -\verb|equalize| only works if the kernel is patched. - - \end{itemize} diff --git a/ip/iproute.c b/ip/iproute.c index b60926da..1d73ab87 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -73,7 +73,6 @@ static void usage(void) fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n"); fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n"); - fprintf(stderr, "FLAGS := [ equalize ]\n"); fprintf(stderr, "MP_ALGO := { rr | drr | random | wrandom }\n"); fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n"); fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n"); @@ -382,8 +381,6 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "onlink "); if (r->rtm_flags & RTNH_F_PERVASIVE) fprintf(fp, "pervasive "); - if (r->rtm_flags & RTM_F_EQUALIZE) - fprintf(fp, "equalize "); if (r->rtm_flags & RTM_F_NOTIFY) fprintf(fp, "notify "); @@ -423,9 +420,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) PRTFL(FAST, "fastroute"); PRTFL(NOTIFY, "notify"); PRTFL(TPROXY, "proxy"); -#ifdef RTCF_EQUALIZE - PRTFL(EQUALIZE, "equalize"); -#endif + if (flags) fprintf(fp, "%s%x> ", first ? "<" : "", flags); if (tb[RTA_CACHEINFO]) { @@ -878,9 +873,6 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) addattr32(&req.n, sizeof(req), RTA_FLOW, realm); } else if (strcmp(*argv, "onlink") == 0) { req.r.rtm_flags |= RTNH_F_ONLINK; - } else if (matches(*argv, "equalize") == 0 || - strcmp(*argv, "eql") == 0) { - req.r.rtm_flags |= RTM_F_EQUALIZE; } else if (strcmp(*argv, "nexthop") == 0) { nhs_ok = 1; break; diff --git a/man/man8/ip.8 b/man/man8/ip.8 index 273be92b..0abd7851 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -212,10 +212,6 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" .BR host " | " link " | " global " |" .IR NUMBER " ]" -.ti -8 -.IR FLAGS " := [ " -.BR equalize " ]" - .ti -8 .IR NHFLAGS " := [ " .BR onlink " | " pervasive " ]" @@ -1596,14 +1592,6 @@ to assign (or not to assign) protocol tags. pretend that the nexthop is directly attached to this link, even if it does not match any interface prefix. -.TP -.B equalize -allow packet by packet randomization on multipath routes. -Without this modifier, the route will be frozen to one selected -nexthop, so that load splitting will only occur on per-flow base. -.B equalize -only works if the kernel is patched. - .SS ip route delete - delete route .B ip route del From a1b9ffccc29f160618d6018d6934d90daa959592 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Mon, 14 Sep 2009 17:01:43 -0400 Subject: [PATCH 45/59] ip: print "temporary" for IPv6 temp addresses IPv6 addresses that have IFA_F_SECONDARY set are actually temporary addresses, hence the IFA_F_TEMPORARY equivalent. Change the output in this case and allow filtering on the word "temporary". Signed-off-by: Brian Haley --- ip/ipaddress.c | 10 +++++++--- man/man8/ip.8 | 6 +++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 91c7b1ba..e9256d91 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -72,7 +72,7 @@ static void usage(void) fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n"); fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n"); - fprintf(stderr, " tentative | deprecated | dadfailed |\n"); + fprintf(stderr, " tentative | deprecated | dadfailed | temporary |\n"); fprintf(stderr, " CONFFLAG-LIST ]\n"); fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"); fprintf(stderr, "CONFFLAG := [ home | nodad ]\n"); @@ -484,7 +484,10 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1))); if (ifa->ifa_flags&IFA_F_SECONDARY) { ifa->ifa_flags &= ~IFA_F_SECONDARY; - fprintf(fp, "secondary "); + if (ifa->ifa_family == AF_INET6) + fprintf(fp, "temporary "); + else + fprintf(fp, "secondary "); } if (ifa->ifa_flags&IFA_F_TENTATIVE) { ifa->ifa_flags &= ~IFA_F_TENTATIVE; @@ -661,7 +664,8 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush) } else if (strcmp(*argv, "permanent") == 0) { filter.flags |= IFA_F_PERMANENT; filter.flagmask |= IFA_F_PERMANENT; - } else if (strcmp(*argv, "secondary") == 0) { + } else if (strcmp(*argv, "secondary") == 0 || + strcmp(*argv, "temporary") == 0) { filter.flags |= IFA_F_SECONDARY; filter.flagmask |= IFA_F_SECONDARY; } else if (strcmp(*argv, "primary") == 0) { diff --git a/man/man8/ip.8 b/man/man8/ip.8 index 0abd7851..ccc800fe 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -97,7 +97,7 @@ ip \- show / manipulate routing, devices, policy routing and tunnels .ti -8 .IR FLAG " := " .RB "[ " permanent " | " dynamic " | " secondary " | " primary " | "\ -tentative " | " deprecated " | " dadfailed " ]" +tentative " | " deprecated " | " dadfailed " | " temporary " ]" .ti -8 .BR "ip addrlabel" " { " add " | " del " } " prefix @@ -1040,6 +1040,10 @@ address detection. (IPv6 only) only list addresses which have failed duplicate address detection. +.TP +.B temporary +(IPv6 only) only list temporary addresses. + .TP .BR primary " and " secondary only list primary (or secondary) addresses. From b88215c4689d94628d3aa0ac112c290b6373860a Mon Sep 17 00:00:00 2001 From: Alexandre Cassen Date: Wed, 16 Dec 2009 02:38:29 +0000 Subject: [PATCH 46/59] IPv6: 6rd iproute2 support This patch provides iproute2 facilities to configure 6rd tunnel. To configure a 6rd tunnel, you need to configure a sit tunnel and set 6rd prefix as following : ip tunnel add sit1 mode sit local a.b.c.d ttl 64 ip tunnel 6rd dev sit1 6rd-prefix xxxx:yyyy::/z Optionally you can provide a relay prefix : ip tunnel 6rd dev sit1 6rd-relay_prefix e.f.g.h/i Finally you can reset previous tunnel settings : ip tunnel 6rd dev sit1 6rd-reset Signed-off-by: Alexandre Cassen --- ip/iptunnel.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++- ip/tunnel.c | 17 +++++++++++++- ip/tunnel.h | 2 ++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/ip/iptunnel.c b/ip/iptunnel.c index dcd7ee6f..1cd9fbd6 100644 --- a/ip/iptunnel.c +++ b/ip/iptunnel.c @@ -32,10 +32,11 @@ static void usage(void) __attribute__((noreturn)); static void usage(void) { - fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl } [ NAME ]\n"); + fprintf(stderr, "Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]\n"); fprintf(stderr, " [ mode { ipip | gre | sit | isatap } ] [ remote ADDR ] [ local ADDR ]\n"); fprintf(stderr, " [ [i|o]seq ] [ [i|o]key KEY ] [ [i|o]csum ]\n"); fprintf(stderr, " [ prl-default ADDR ] [ prl-nodefault ADDR ] [ prl-delete ADDR ]\n"); + fprintf(stderr, " [ 6rd-prefix ADDR ] [ 6rd-relay_prefix ADDR ] [ 6rd-reset ]\n"); fprintf(stderr, " [ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]\n"); fprintf(stderr, "\n"); fprintf(stderr, "Where: NAME := STRING\n"); @@ -302,11 +303,13 @@ static int do_del(int argc, char **argv) static void print_tunnel(struct ip_tunnel_parm *p) { + struct ip_tunnel_6rd ip6rd; char s1[1024]; char s2[1024]; char s3[64]; char s4[64]; + memset(&ip6rd, 0, sizeof(ip6rd)); inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3)); inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4)); @@ -362,6 +365,17 @@ static void print_tunnel(struct ip_tunnel_parm *p) if (!(p->iph.frag_off&htons(IP_DF))) printf(" nopmtudisc"); + if (!tnl_ioctl_get_6rd(p->name, &ip6rd) && ip6rd.prefixlen) { + printf(" 6rd-prefix %s/%u ", + inet_ntop(AF_INET6, &ip6rd.prefix, s1, sizeof(s1)), + ip6rd.prefixlen); + if (ip6rd.relay_prefix) { + printf("6rd-relay_prefix %s/%u ", + format_host(AF_INET, 4, &ip6rd.relay_prefix, s1, sizeof(s1)), + ip6rd.relay_prefixlen); + } + } + if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key) printf(" key %s", s3); else if ((p->i_flags|p->o_flags)&GRE_KEY) { @@ -528,6 +542,52 @@ static int do_prl(int argc, char **argv) return tnl_prl_ioctl(cmd, medium, &p); } +static int do_6rd(int argc, char **argv) +{ + struct ip_tunnel_6rd ip6rd; + int devname = 0; + int cmd = 0; + char medium[IFNAMSIZ]; + inet_prefix prefix; + + memset(&ip6rd, 0, sizeof(ip6rd)); + memset(&medium, 0, sizeof(medium)); + + while (argc > 0) { + if (strcmp(*argv, "6rd-prefix") == 0) { + NEXT_ARG(); + if (get_prefix(&prefix, *argv, AF_INET6)) + invarg("invalid 6rd_prefix\n", *argv); + cmd = SIOCADD6RD; + memcpy(&ip6rd.prefix, prefix.data, 16); + ip6rd.prefixlen = prefix.bitlen; + } else if (strcmp(*argv, "6rd-relay_prefix") == 0) { + NEXT_ARG(); + if (get_prefix(&prefix, *argv, AF_INET)) + invarg("invalid 6rd-relay_prefix\n", *argv); + cmd = SIOCADD6RD; + memcpy(&ip6rd.relay_prefix, prefix.data, 4); + ip6rd.relay_prefixlen = prefix.bitlen; + } else if (strcmp(*argv, "6rd-reset") == 0) { + cmd = SIOCDEL6RD; + } else if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); + strncpy(medium, *argv, IFNAMSIZ-1); + devname++; + } else { + fprintf(stderr,"%s: Invalid 6RD parameter.\n", *argv); + exit(-1); + } + argc--; argv++; + } + if (devname == 0) { + fprintf(stderr, "Must specify dev.\n"); + exit(-1); + } + + return tnl_6rd_ioctl(cmd, medium, &ip6rd); +} + int do_iptunnel(int argc, char **argv) { switch (preferred_family) { @@ -561,6 +621,8 @@ int do_iptunnel(int argc, char **argv) return do_show(argc-1, argv+1); if (matches(*argv, "prl") == 0) return do_prl(argc-1, argv+1); + if (matches(*argv, "6rd") == 0) + return do_6rd(argc-1, argv+1); if (matches(*argv, "help") == 0) usage(); } else diff --git a/ip/tunnel.c b/ip/tunnel.c index d1296e68..d389e866 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -168,7 +168,7 @@ int tnl_del_ioctl(const char *basedev, const char *name, void *p) return err; } -int tnl_prl_ioctl(int cmd, const char *name, void *p) +static int tnl_gen_ioctl(int cmd, const char *name, void *p) { struct ifreq ifr; int fd; @@ -183,3 +183,18 @@ int tnl_prl_ioctl(int cmd, const char *name, void *p) close(fd); return err; } + +int tnl_prl_ioctl(int cmd, const char *name, void *p) +{ + return tnl_gen_ioctl(cmd, name, p); +} + +int tnl_6rd_ioctl(int cmd, const char *name, void *p) +{ + return tnl_gen_ioctl(cmd, name, p); +} + +int tnl_ioctl_get_6rd(const char *name, void *p) +{ + return tnl_gen_ioctl(SIOCGET6RD, name, p); +} diff --git a/ip/tunnel.h b/ip/tunnel.h index 0661e277..ded226b4 100644 --- a/ip/tunnel.h +++ b/ip/tunnel.h @@ -32,5 +32,7 @@ int tnl_get_ioctl(const char *basedev, void *p); int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p); int tnl_del_ioctl(const char *basedev, const char *name, void *p); int tnl_prl_ioctl(int cmd, const char *name, void *p); +int tnl_6rd_ioctl(int cmd, const char *name, void *p); +int tnl_ioctl_get_6rd(const char *name, void *p); #endif From 7cd96eee69865e8e973a9364e0110c286108a283 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 24 Feb 2010 19:56:50 -0800 Subject: [PATCH 47/59] iproute2-10224 Final 2.6.33 version --- include/SNAPSHOT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index 0da650b4..f07d1e71 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "100205"; +static const char SNAPSHOT[] = "100224"; From f703129d3441be2e014c58ae3e95314ba769315a Mon Sep 17 00:00:00 2001 From: Hagen Paul Pfeifer Date: Sun, 24 Jan 2010 12:31:05 +0000 Subject: [PATCH 48/59] tc: add new queue discipline: head drop fifo This adds the required changes to gain access to the head drop classfull queuing discipline named pfifo_head_drop. In difference to pfifo or pfifo_fast this queuing discipline will drop the first packet in the case of queue congestion. As a result the queue contain always the freshest packets. To replace the current a root queueing discipline for eth0: $ tc qdisc replace dev eth0 root pfifo_head_drop And show statistics: $ tc -s qdisc show dev eth0 Signed-off-by: Hagen Paul Pfeifer --- tc/q_fifo.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tc/q_fifo.c b/tc/q_fifo.c index f561752d..6242a98b 100644 --- a/tc/q_fifo.c +++ b/tc/q_fifo.c @@ -25,7 +25,7 @@ static void explain(void) { - fprintf(stderr, "Usage: ... [p|b]fifo [ limit NUMBER ]\n"); + fprintf(stderr, "Usage: ... <[p|b]fifo | pfifo_head_drop> [ limit NUMBER ]\n"); } static int fifo_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n) @@ -89,6 +89,12 @@ struct qdisc_util pfifo_qdisc_util = { .print_qopt = fifo_print_opt, }; +struct qdisc_util pfifo_head_drop_qdisc_util = { + .id = "pfifo_head_drop", + .parse_qopt = fifo_parse_opt, + .print_qopt = fifo_print_opt, +}; + extern int prio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt); struct qdisc_util pfifo_fast_qdisc_util = { .id = "pfifo_fast", From f5fd80039fb95242ad8d5796bdf2f52190a058b4 Mon Sep 17 00:00:00 2001 From: laurent chavey Date: Tue, 15 Dec 2009 13:05:15 +0000 Subject: [PATCH 49/59] Add initrwnd to iproute2 Add initrwnd option parsing to iproute. This option uses the new rtnetlink init_rcvwnd to set the TCP initial receive window size advertised by passive and active TCP connections. Signed-off-by: Laurent Chavey --- doc/ip-cref.tex | 7 +++++++ ip/iproute.c | 13 ++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex index 7bb562e1..056e3bf5 100644 --- a/doc/ip-cref.tex +++ b/doc/ip-cref.tex @@ -1336,6 +1336,13 @@ peers are allowed to send to us. MSS (``Maximal Segment Size'') for same connection. The default is zero, meaning to use the values specified in~\cite{RFC2414}. ++\item \verb|initrwnd NUMBER| + ++--- [2.6.33+ only] Initial receive window size for connections to ++ this destination. The actual window size is this value multiplied ++ by the MSS (''Maximal Segment Size'') of the connection. The default ++ value is zero, meaning to use Slow Start value. + \item \verb|nexthop NEXTHOP| --- the nexthop of a multipath route. \verb|NEXTHOP| is a complex value diff --git a/ip/iproute.c b/ip/iproute.c index 1d73ab87..8252e182 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -46,6 +46,7 @@ static const char *mx_names[RTAX_MAX+1] = { [RTAX_INITCWND] = "initcwnd", [RTAX_FEATURES] = "features", [RTAX_RTO_MIN] = "rto_min", + [RTAX_INITRWND] = "initrwnd", }; static void usage(void) __attribute__((noreturn)); @@ -68,7 +69,7 @@ static void usage(void) fprintf(stderr, " [ rtt TIME ] [ rttvar TIME ] [reordering NUMBER ]\n"); fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n"); fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n"); - fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] \n"); + fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n"); fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n"); fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n"); fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); @@ -844,6 +845,16 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) if (get_unsigned(&win, *argv, 0)) invarg("\"initcwnd\" value is invalid\n", *argv); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITCWND, win); + } else if (matches(*argv, "initrwnd") == 0) { + unsigned win; + NEXT_ARG(); + if (strcmp(*argv, "lock") == 0) { + mxlock |= (1< Date: Wed, 3 Mar 2010 16:22:00 -0800 Subject: [PATCH 50/59] Update headers for 2.6.33-net-next Use santized headers from net-next tree. --- include/linux/can/netlink.h | 17 ++++++++++++++--- include/linux/if_link.h | 30 ++++++++++++++++++++++++++++++ include/linux/netdevice.h | 1 + include/linux/netfilter/x_tables.h | 18 ++++++++++++++++-- include/linux/rtnetlink.h | 2 ++ include/linux/xfrm.h | 12 +++++++++--- 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/include/linux/can/netlink.h b/include/linux/can/netlink.h index 9ecbb787..3250de93 100644 --- a/include/linux/can/netlink.h +++ b/include/linux/can/netlink.h @@ -69,6 +69,14 @@ enum can_state { CAN_STATE_MAX }; +/* + * CAN bus error counters + */ +struct can_berr_counter { + __u16 txerr; + __u16 rxerr; +}; + /* * CAN controller mode */ @@ -77,9 +85,11 @@ struct can_ctrlmode { __u32 flags; }; -#define CAN_CTRLMODE_LOOPBACK 0x1 /* Loopback mode */ -#define CAN_CTRLMODE_LISTENONLY 0x2 /* Listen-only mode */ -#define CAN_CTRLMODE_3_SAMPLES 0x4 /* Triple sampling mode */ +#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */ +#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */ +#define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */ +#define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */ +#define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */ /* * CAN device statistics @@ -105,6 +115,7 @@ enum { IFLA_CAN_CTRLMODE, IFLA_CAN_RESTART_MS, IFLA_CAN_RESTART, + IFLA_CAN_BERR_COUNTER, __IFLA_CAN_MAX }; diff --git a/include/linux/if_link.h b/include/linux/if_link.h index cbefb3bc..5110b96a 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -78,6 +78,11 @@ enum { #define IFLA_LINKINFO IFLA_LINKINFO IFLA_NET_NS_PID, IFLA_IFALIAS, + IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */ + IFLA_VF_MAC, /* Hardware queue specific attributes */ + IFLA_VF_VLAN, + IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ + IFLA_VFINFO, __IFLA_MAX }; @@ -194,4 +199,29 @@ enum macvlan_mode { MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ }; +/* SR-IOV virtual function managment section */ + +struct ifla_vf_mac { + __u32 vf; + __u8 mac[32]; /* MAX_ADDR_LEN */ +}; + +struct ifla_vf_vlan { + __u32 vf; + __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ + __u32 qos; +}; + +struct ifla_vf_tx_rate { + __u32 vf; + __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ +}; + +struct ifla_vf_info { + __u32 vf; + __u8 mac[32]; + __u32 vlan; + __u32 qos; + __u32 tx_rate; +}; #endif /* _LINUX_IF_LINK_H */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9035dfaf..3dbf0cc4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -28,6 +28,7 @@ #include #include #include +#include #define MAX_ADDR_LEN 32 /* Largest hardware address length */ diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index ccb56410..1616f4fb 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -93,8 +93,7 @@ struct _xt_align { __u64 u64; }; -#define XT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) \ - & ~(__alignof__(struct _xt_align)-1)) +#define XT_ALIGN(s) ALIGN((s), __alignof__(struct _xt_align)) /* Standard return verdict, or do jump. */ #define XT_STANDARD_TARGET "" @@ -165,4 +164,19 @@ struct xt_counters_info { XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args) +/* pos is normally a struct ipt_entry/ip6t_entry/etc. */ +#define xt_entry_foreach(pos, ehead, esize) \ + for ((pos) = (typeof(pos))(ehead); \ + (pos) < (typeof(pos))((char *)(ehead) + (esize)); \ + (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset)) + +/* can only be xt_entry_match, so no use of typeof here */ +#define xt_ematch_foreach(pos, entry) \ + for ((pos) = (struct xt_entry_match *)entry->elems; \ + (pos) < (struct xt_entry_match *)((char *)(entry) + \ + (entry)->target_offset); \ + (pos) = (struct xt_entry_match *)((char *)(pos) + \ + (pos)->u.match_size)) + + #endif /* _X_TABLES_H */ diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 5b46173f..e94981d8 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -362,6 +362,8 @@ enum { #define RTAX_FEATURES RTAX_FEATURES RTAX_RTO_MIN, #define RTAX_RTO_MIN RTAX_RTO_MIN + RTAX_INITRWND, +#define RTAX_INITRWND RTAX_INITRWND __RTAX_MAX }; diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 9686820b..07f2b63e 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -267,8 +267,8 @@ enum xfrm_attr_type_t { XFRMA_ALG_COMP, /* struct xfrm_algo */ XFRMA_ENCAP, /* struct xfrm_algo + struct xfrm_encap_tmpl */ XFRMA_TMPL, /* 1 or more struct xfrm_user_tmpl */ - XFRMA_SA, - XFRMA_POLICY, + XFRMA_SA, /* struct xfrm_usersa_info */ + XFRMA_POLICY, /*struct xfrm_userpolicy_info */ XFRMA_SEC_CTX, /* struct xfrm_sec_ctx */ XFRMA_LTIME_VAL, XFRMA_REPLAY_VAL, @@ -276,17 +276,23 @@ enum xfrm_attr_type_t { XFRMA_ETIMER_THRESH, XFRMA_SRCADDR, /* xfrm_address_t */ XFRMA_COADDR, /* xfrm_address_t */ - XFRMA_LASTUSED, + XFRMA_LASTUSED, /* unsigned long */ XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */ XFRMA_MIGRATE, XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */ XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */ XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */ + XFRMA_MARK, /* struct xfrm_mark */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) }; +struct xfrm_mark { + __u32 v; /* value */ + __u32 m; /* mask */ +}; + enum xfrm_sadattr_type_t { XFRMA_SAD_UNSPEC, XFRMA_SAD_CNT, From 3e4f6a380a14a3100b1aa97a94c46d8712080863 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 3 Mar 2010 16:31:09 -0800 Subject: [PATCH 51/59] Fix line numbering on batch commands ip command should not keep track of lineno, that is done in getcmdline(). --- ip/ip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ip/ip.c b/ip/ip.c index ace8cc6f..5ebd2158 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -96,7 +96,6 @@ static int batch(const char *name) char *line = NULL; size_t len = 0; int ret = 0; - int lineno = 0; if (name && strcmp(name, "-") != 0) { if (freopen(name, "r", stdin) == NULL) { @@ -111,6 +110,7 @@ static int batch(const char *name) return -1; } + cmdlineno = 0; while (getcmdline(&line, &len, stdin) != -1) { char *largv[100]; int largc; @@ -120,7 +120,7 @@ static int batch(const char *name) continue; /* blank line */ if (do_cmd(largv[0], largc, largv)) { - fprintf(stderr, "Command failed %s:%d\n", name, lineno); + fprintf(stderr, "Command failed %s:%d\n", name, cmdlineno); ret = 1; if (!force) break; From 46dab6e925f8317909698ed1cd8ccbe95b5a3f40 Mon Sep 17 00:00:00 2001 From: "Williams, Mitch A" Date: Wed, 10 Feb 2010 01:47:29 +0000 Subject: [PATCH 52/59] Update man page to indicate current options Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- man/man8/ip.8 | 73 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/man/man8/ip.8 b/man/man8/ip.8 index ccc800fe..3efa0455 100644 --- a/man/man8/ip.8 +++ b/man/man8/ip.8 @@ -53,7 +53,23 @@ ip \- show / manipulate routing, devices, policy routing and tunnels .IR MTU " |" .br .B netns -.IR PID " }" +.IR PID " |" +.br +.B alias +.IR NAME " |" +.br +.B vf +.IR NUM " [" +.B mac +.IR LLADDR " ] [" +.B vlan +.IR VLANID " [ " +.B qos +.IR VLAN-QOS " ] ] [" +.B rate +.IR TXRATE " ]" +.BR " }" + .ti -8 .B ip link show @@ -822,7 +838,9 @@ display and change the state of devices. .TP .BI dev " NAME " (default) .I NAME -specifies network device to operate on. +specifies network device to operate on. When configuring SR-IOV Virtual Fuction +(VF) devices, this keyword should specify the associated Physical Function (PF) +device. .TP .BR up " and " down @@ -884,7 +902,56 @@ the interface is .TP .BI netns " PID" move the device to the network namespace associated with the process -.IR "PID" . +.IR "PID". + +.TP +.BI alias " NAME" +give the device a symbolic name for easy reference. + +.TP +.BI vf " NUM" +specify a Virtual Function device to be configured. The associated PF device +must be specified using the +.B dev +parameter. + +.in +8 +.BI mac " LLADDRESS" +- change the station address for the specified VF. The +.B vf +parameter must be specified. + +.sp +.BI vlan " VLANID" +- change the assigned VLAN for the specified VF. When specified, all traffic +sent from the VF will be tagged with the specified VLAN ID. Incoming traffic +will be filtered for the specified VLAN ID, and will have all VLAN tags +stripped before being passed to the VF. Setting this parameter to 0 disables +VLAN tagging and filtering. The +.B vf +parameter must be specified. + +.sp +.BI qos " VLAN-QOS" +- assign VLAN QOS (priority) bits for the VLAN tag. When specified, all VLAN +tags transmitted by the VF will include the specified priority bits in the +VLAN tag. If not specified, the value is assumed to be 0. Both the +.B vf +and +.B vlan +parameters must be specified. Setting both +.B vlan +and +.B qos +as 0 disables VLAN tagging and filtering for the VF. + +.sp +.BI rate " TXRATE" +- change the allowed transmit bandwidth, in Mbps, for the specified VF. +Setting this parameter to 0 disables rate limiting. The +.B vf +parameter must be specified. +.in -8 .PP .B Warning: From ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87 Mon Sep 17 00:00:00 2001 From: "Williams, Mitch A" Date: Wed, 10 Feb 2010 01:47:08 +0000 Subject: [PATCH 53/59] ip: Add support for setting and showing SR-IOV virtual funtion link params Add support to 'ip' for setting and showing SR-IOV virtual function link parameters. Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- ip/ipaddress.c | 25 ++++++++++++++++++++++++ ip/iplink.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/ip/ipaddress.c b/ip/ipaddress.c index e9256d91..3186f9cb 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -331,6 +331,31 @@ int print_linkinfo(const struct sockaddr_nl *who, ); } } + if (do_link && tb[IFLA_VFINFO] && tb[IFLA_NUM_VF]) { + SPRINT_BUF(b1); + struct rtattr *rta = tb[IFLA_VFINFO]; + struct ifla_vf_info *ivi; + int i; + for (i = 0; i < *(int *)RTA_DATA(tb[IFLA_NUM_VF]); i++) { + if (rta->rta_type != IFLA_VFINFO) { + fprintf(stderr, "BUG: rta type is %d\n", rta->rta_type); + break; + } + ivi = RTA_DATA(rta); + fprintf(fp, "\n vf %d: MAC %s", + ivi->vf, + ll_addr_n2a((unsigned char *)&ivi->mac, + ETH_ALEN, 0, b1, sizeof(b1))); + if (ivi->vlan) + fprintf(fp, ", vlan %d", ivi->vlan); + if (ivi->qos) + fprintf(fp, ", qos %d", ivi->qos); + if (ivi->tx_rate) + fprintf(fp, ", tx rate %d (Mbps_", + ivi->tx_rate); + rta = (struct rtattr *)((char *)rta + RTA_ALIGN(rta->rta_len)); + } + } fprintf(fp, "\n"); fflush(fp); return 0; diff --git a/ip/iplink.c b/ip/iplink.c index 32cce240..97fca8be 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -68,6 +68,9 @@ void iplink_usage(void) fprintf(stderr, " [ mtu MTU ]\n"); fprintf(stderr, " [ netns PID ]\n"); fprintf(stderr, " [ alias NAME ]\n"); + fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n"); + fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n"); + fprintf(stderr, " [ rate TXRATE ] ] \n"); fprintf(stderr, " ip link show [ DEVICE ]\n"); if (iplink_have_newlink()) { @@ -181,6 +184,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, int qlen = -1; int mtu = -1; int netns = -1; + int vf = -1; ret = argc; @@ -278,6 +282,54 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, req->i.ifi_flags |= IFF_NOARP; } else return on_off("noarp"); + } else if (strcmp(*argv, "vf") == 0) { + NEXT_ARG(); + if (get_integer(&vf, *argv, 0)) { + invarg("Invalid \"vf\" value\n", *argv); + } + } else if (matches(*argv, "mac") == 0) { + struct ifla_vf_mac ivm; + NEXT_ARG(); + if (vf < 0) { + missarg("vf"); + } + ivm.vf = vf; + len = ll_addr_a2n((char *)ivm.mac, 32, *argv); + if (len < 0) + return -1; + addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC, &ivm, sizeof(ivm)); + } else if (matches(*argv, "vlan") == 0) { + struct ifla_vf_vlan ivv; + NEXT_ARG(); + if (vf < 0) { + missarg("vf"); + } + if (get_unsigned(&ivv.vlan, *argv, 0)) { + invarg("Invalid \"vlan\" value\n", *argv); + } + ivv.vf = vf; + ivv.qos = 0; + if (NEXT_ARG_OK()) { + NEXT_ARG(); + if (matches(*argv, "qos") == 0) { + NEXT_ARG(); + if (get_unsigned(&ivv.qos, *argv, 0)) { + invarg("Invalid \"qos\" value\n", *argv); + } + } + } + addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN, &ivv, sizeof(ivv)); + } else if (matches(*argv, "rate") == 0) { + struct ifla_vf_tx_rate ivt; + NEXT_ARG(); + if (vf < 0) { + missarg("vf"); + } + if (get_unsigned(&ivt.rate, *argv, 0)) { + invarg("Invalid \"rate\" value\n", *argv); + } + ivt.vf = vf; + addattr_l(&req->n, sizeof(*req), IFLA_VF_TX_RATE, &ivt, sizeof(ivt)); #ifdef IFF_DYNAMIC } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); From 6e46ec813b7f06a85acb5a348dfc1a25ea488024 Mon Sep 17 00:00:00 2001 From: "Williams, Mitch A" Date: Wed, 10 Feb 2010 01:46:47 +0000 Subject: [PATCH 54/59] libnetlink: Modify the parser to track first duplicated attributes Modify the parser to keep track of the first of any duplicated attributes, instead of the last. This is required for VF configuration reporting, where multiple attributes of the same type are added sequentially. Signed-off-by: Mitch Williams Signed-off-by: Jeff Kirsher --- lib/libnetlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 4ba60190..cfeb8941 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -644,7 +644,7 @@ int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) { memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); while (RTA_OK(rta, len)) { - if (rta->rta_type <= max) + if ((rta->rta_type <= max) && (!tb[rta->rta_type])) tb[rta->rta_type] = rta; rta = RTA_NEXT(rta,len); } From e906975a53df2614a08d32017aa6e3c70f204a2d Mon Sep 17 00:00:00 2001 From: jamal Date: Mon, 15 Feb 2010 01:51:01 +0000 Subject: [PATCH 55/59] skbedit: use get_u32 for parsing mark parsing a mark as a classid allows for acceptance of strange informal input. cheers, jamal commit aad0da6507ff8a95a63ed8e529c05f52be5b0e75 Author: Jamal Hadi Salim Date: Mon Feb 15 06:45:29 2010 -0500 skbedit: use get_u32 for parsing mark get_u32 is the more appropriate parser for a mark. Signed-off-by: Jamal Hadi Salim --- tc/m_skbedit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c index 5d1a96a8..990b9c7d 100644 --- a/tc/m_skbedit.c +++ b/tc/m_skbedit.c @@ -86,7 +86,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, } else if (matches(*argv, "mark") == 0) { flags |= SKBEDIT_F_MARK; NEXT_ARG(); - if (get_tc_classid(&mark, *argv)) { + if (get_u32(&mark, *argv, 0)) { fprintf(stderr, "Illegal mark\n"); return -1; } From ee675e87149eeaed8f7ae43bdc8648b83a934eb8 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Tue, 23 Feb 2010 03:15:11 +0000 Subject: [PATCH 56/59] xfrm: policy by mark Add support for SP manipulation by mark Signed-off-by: Jamal Hadi Salim --- ip/xfrm_policy.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index 27884773..121afa13 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -54,8 +54,8 @@ static void usage(void) __attribute__((noreturn)); static void usage(void) { fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] [ ptype PTYPE ]\n"); - fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ]\n"); - fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ] [ ptype PTYPE ]\n"); + fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ] [mark MARK [mask MASK]]\n"); + fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ] [ ptype PTYPE ] [mark MARK [mask MASK]]\n"); fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ dir DIR ] [ SELECTOR ]\n"); fprintf(stderr, " [ index INDEX ] [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ]\n"); fprintf(stderr, "Usage: ip xfrm policy flush [ ptype PTYPE ]\n"); @@ -235,6 +235,7 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv) struct xfrm_userpolicy_type upt; char tmpls_buf[XFRM_TMPLS_BUF_SIZE]; int tmpls_len = 0; + struct xfrm_mark mark = {0, 0}; memset(&req, 0, sizeof(req)); memset(&upt, 0, sizeof(upt)); @@ -258,6 +259,8 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv) NEXT_ARG(); xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv); + } else if (strcmp(*argv, "mark") == 0) { + xfrm_parse_mark(&mark, &argc, &argv); } else if (strcmp(*argv, "index") == 0) { NEXT_ARG(); if (get_u32(&req.xpinfo.index, *argv, 0)) @@ -334,6 +337,16 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv) (void *)tmpls_buf, tmpls_len); } + if (mark.m & mark.v) { + int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK, + (void *)&mark, sizeof(mark)); + if (r < 0) { + fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__); + exit(1); + } + } + + if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) exit(1); @@ -515,6 +528,7 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete, char *indexp = NULL; char *ptypep = NULL; struct xfrm_userpolicy_type upt; + struct xfrm_mark mark = {0, 0}; memset(&req, 0, sizeof(req)); memset(&upt, 0, sizeof(upt)); @@ -532,6 +546,8 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete, NEXT_ARG(); xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv); + } else if (strcmp(*argv, "mark") == 0) { + xfrm_parse_mark(&mark, &argc, &argv); } else if (strcmp(*argv, "index") == 0) { if (indexp) duparg("index", *argv); @@ -584,6 +600,15 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete, if (req.xpid.sel.family == AF_UNSPEC) req.xpid.sel.family = AF_INET; + if (mark.m & mark.v) { + int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK, + (void *)&mark, sizeof(mark)); + if (r < 0) { + fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__); + exit(1); + } + } + if (rtnl_talk(&rth, &req.n, 0, 0, res_nlbuf, NULL, NULL) < 0) exit(2); From f6fd52e626d7897e9df03331dbeb149beacb53ba Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Tue, 23 Feb 2010 03:15:10 +0000 Subject: [PATCH 57/59] xfrm: Introduce xfrm by mark This patch carries basic infrastructure. You need to make sure that the proper include/linux/xfrm.h is included for it to compile. Example: --- ip/ipxfrm.c | 40 ++++++++++++++++++++++++++++++++++++++++ ip/xfrm.h | 1 + 2 files changed, 41 insertions(+) diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index 7dc36f36..78e1926d 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -629,9 +629,48 @@ static void xfrm_tmpl_print(struct xfrm_user_tmpl *tmpls, int len, } } +int xfrm_parse_mark(struct xfrm_mark *mark, int *argcp, char ***argvp) +{ + int argc = *argcp; + char **argv = *argvp; + + NEXT_ARG(); + if (get_u32(&mark->v, *argv, 0)) { + invarg("Illegal \"mark\" value\n", *argv); + } + if (argc > 1) + NEXT_ARG(); + else { /* last entry on parse line */ + mark->m = 0xffffffff; + goto done; + } + + if (strcmp(*argv, "mask") == 0) { + NEXT_ARG(); + if (get_u32(&mark->m, *argv, 0)) { + invarg("Illegal \"mark\" mask\n", *argv); + } + } else { + mark->m = 0xffffffff; + PREV_ARG(); + } + +done: + *argcp = argc; + *argvp = argv; + + return 0; +} + void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, FILE *fp, const char *prefix) { + if (tb[XFRMA_MARK]) { + struct rtattr *rta = tb[XFRMA_MARK]; + struct xfrm_mark *m = (struct xfrm_mark *) RTA_DATA(rta); + fprintf(fp, "\tmark %d/0x%x\n", m->v, m->m); + } + if (tb[XFRMA_ALG_AUTH]) { struct rtattr *rta = tb[XFRMA_ALG_AUTH]; xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta), @@ -740,6 +779,7 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, fprintf(fp, "%s", strxf_time(lastused)); fprintf(fp, "%s", _SL_); } + } static int xfrm_selector_iszero(struct xfrm_selector *s) diff --git a/ip/xfrm.h b/ip/xfrm.h index 104fb208..d3ca5c53 100644 --- a/ip/xfrm.h +++ b/ip/xfrm.h @@ -121,6 +121,7 @@ int xfrm_xfrmproto_is_ipsec(__u8 proto); int xfrm_xfrmproto_is_ro(__u8 proto); int xfrm_xfrmproto_getbyname(char *name); int xfrm_algotype_getbyname(char *name); +int xfrm_parse_mark(struct xfrm_mark *mark, int *argcp, char ***argvp); const char *strxf_xfrmproto(__u8 proto); const char *strxf_algotype(int type); const char *strxf_mask8(__u8 mask); From c90cda94006ed9d4a53750bd036adbfe1ae7069d Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Tue, 23 Feb 2010 03:15:12 +0000 Subject: [PATCH 58/59] xfrm: add support for SA by mark Add support for SA manipulation by mark Signed-off-by: Jamal Hadi Salim --- ip/xfrm_state.c | 66 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index 32238ab7..38d40391 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -67,7 +67,7 @@ static void usage(void) fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM_PROTO ]\n"); fprintf(stderr, "Usage: ip xfrm state count \n"); - fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n"); + fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ] [mark MARK [mask MASK]]\n"); //fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n"); fprintf(stderr, "XFRM_PROTO := [ "); fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP)); @@ -246,6 +246,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) char *aalgop = NULL; char *calgop = NULL; char *coap = NULL; + struct xfrm_mark mark = {0, 0}; memset(&req, 0, sizeof(req)); memset(&replay, 0, sizeof(replay)); @@ -264,6 +265,8 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv) if (strcmp(*argv, "mode") == 0) { NEXT_ARG(); xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv); + } else if (strcmp(*argv, "mark") == 0) { + xfrm_parse_mark(&mark, &argc, &argv); } else if (strcmp(*argv, "reqid") == 0) { NEXT_ARG(); xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv); @@ -440,6 +443,15 @@ parse_algo: exit(1); } + if (mark.m & mark.v) { + int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK, + (void *)&mark, sizeof(mark)); + if (r < 0) { + fprintf(stderr, "XFRMA_MARK failed\n"); + exit(1); + } + } + switch (req.xsinfo.mode) { case XFRM_MODE_TRANSPORT: case XFRM_MODE_TUNNEL: @@ -519,6 +531,7 @@ static int xfrm_state_allocspi(int argc, char **argv) char *idp = NULL; char *minp = NULL; char *maxp = NULL; + struct xfrm_mark mark = {0, 0}; char res_buf[NLMSG_BUF_SIZE]; struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf; @@ -542,6 +555,8 @@ static int xfrm_state_allocspi(int argc, char **argv) if (strcmp(*argv, "mode") == 0) { NEXT_ARG(); xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv); + } else if (strcmp(*argv, "mark") == 0) { + xfrm_parse_mark(&mark, &argc, &argv); } else if (strcmp(*argv, "reqid") == 0) { NEXT_ARG(); xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv); @@ -618,6 +633,15 @@ static int xfrm_state_allocspi(int argc, char **argv) req.xspi.max = 0xffff; } + if (mark.m & mark.v) { + int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK, + (void *)&mark, sizeof(mark)); + if (r < 0) { + fprintf(stderr, "XFRMA_MARK failed\n"); + exit(1); + } + } + if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) exit(1); @@ -763,6 +787,7 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete) } req; struct xfrm_id id; char *idp = NULL; + struct xfrm_mark mark = {0, 0}; memset(&req, 0, sizeof(req)); @@ -774,26 +799,39 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete) while (argc > 0) { xfrm_address_t saddr; - if (idp) - invarg("unknown", *argv); - idp = *argv; + if (strcmp(*argv, "mark") == 0) { + xfrm_parse_mark(&mark, &argc, &argv); + } else { + if (idp) + invarg("unknown", *argv); + idp = *argv; - /* ID */ - memset(&id, 0, sizeof(id)); - memset(&saddr, 0, sizeof(saddr)); - xfrm_id_parse(&saddr, &id, &req.xsid.family, 0, - &argc, &argv); + /* ID */ + memset(&id, 0, sizeof(id)); + memset(&saddr, 0, sizeof(saddr)); + xfrm_id_parse(&saddr, &id, &req.xsid.family, 0, + &argc, &argv); - memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr)); - req.xsid.spi = id.spi; - req.xsid.proto = id.proto; + memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr)); + req.xsid.spi = id.spi; + req.xsid.proto = id.proto; - addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR, - (void *)&saddr, sizeof(saddr)); + addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR, + (void *)&saddr, sizeof(saddr)); + } argc--; argv++; } + if (mark.m & mark.v) { + int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK, + (void *)&mark, sizeof(mark)); + if (r < 0) { + fprintf(stderr, "XFRMA_MARK failed\n"); + exit(1); + } + } + if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) exit(1); From 8a5179466a142172a6f24f5d815c622541b3f61f Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Mon, 22 Feb 2010 22:24:55 +0000 Subject: [PATCH 59/59] iproute2: netlink support for bus-error reporting and counters This patch uses the new features of the kernel's netlink CAN interface making the bus-error reporting configurable and allowing to retrieve the CAN TX and RX bus error counters via netlink interface. Here is the output of my test session showing how to use them: # ip link set can0 up type can bitrate 500000 berr-reporting on # ip -d -s link show can0 2: can0: mtu 16 qdisc pfifo_fast state UNKNOWN qlen 10 link/can can state ERROR-PASSIVE (berr-counter tx 128 rx 0) restart-ms 0 CAN bus error counter values ^^^^^^^^^^^ bitrate 500000 sample-point 0.875 tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1 sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1 clock 8000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 54101 0 1 1 0 RX: bytes packets errors dropped overrun mcast 432808 54101 54101 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 # ifconfig can0 down # ip link set can0 up type can berr-reporting off # candump -t d any,0:0,#FFFFFFFF (0.000000) can0 20000004 [8] 00 08 00 00 00 00 60 00 ERRORFRAME (0.000474) can0 20000004 [8] 00 20 00 00 00 00 80 00 ERRORFRAME ^^ ^^ \ \___ rxerr \_____ txerr Furthermore, the missing support for one-shot mode has been added. Signed-off-by: Wolfgang Grandegger --- ip/iplink_can.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ip/iplink_can.c b/ip/iplink_can.c index 50221e1c..c8af4bc2 100644 --- a/ip/iplink_can.c +++ b/ip/iplink_can.c @@ -30,6 +30,8 @@ static void usage(void) "\t[ loopback { on | off } ]\n" "\t[ listen-only { on | off } ]\n" "\t[ triple-sampling { on | off } ]\n" + "\t[ one-shot { on | off } ]\n" + "\t[ berr-reporting { on | off } ]\n" "\n" "\t[ restart-ms TIME-MS ]\n" "\t[ restart ]\n" @@ -84,6 +86,8 @@ static void print_ctrlmode(FILE *f, __u32 cm) _PF(CAN_CTRLMODE_LOOPBACK, "LOOPBACK"); _PF(CAN_CTRLMODE_LISTENONLY, "LISTEN-ONLY"); _PF(CAN_CTRLMODE_3_SAMPLES, "TRIPLE-SAMPLING"); + _PF(CAN_CTRLMODE_ONE_SHOT, "ONE-SHOT"); + _PF(CAN_CTRLMODE_BERR_REPORTING, "BERR-REPORTING"); #undef _PF if (cm) fprintf(f, "%x", cm); @@ -142,6 +146,14 @@ static int can_parse_opt(struct link_util *lu, int argc, char **argv, NEXT_ARG(); set_ctrlmode("triple-sampling", *argv, &cm, CAN_CTRLMODE_3_SAMPLES); + } else if (matches(*argv, "one-shot") == 0) { + NEXT_ARG(); + set_ctrlmode("one-shot", *argv, &cm, + CAN_CTRLMODE_ONE_SHOT); + } else if (matches(*argv, "berr-reporting") == 0) { + NEXT_ARG(); + set_ctrlmode("berr-reporting", *argv, &cm, + CAN_CTRLMODE_BERR_REPORTING); } else if (matches(*argv, "restart") == 0) { __u32 val = 1; @@ -200,6 +212,13 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) can_state_names[*state] : "UNKNOWN"); } + if (tb[IFLA_CAN_BERR_COUNTER]) { + struct can_berr_counter *bc = + RTA_DATA(tb[IFLA_CAN_BERR_COUNTER]); + + fprintf(f, "(berr-counter tx %d rx %d) ", bc->txerr, bc->rxerr); + } + if (tb[IFLA_CAN_RESTART_MS]) { __u32 *restart_ms = RTA_DATA(tb[IFLA_CAN_RESTART_MS]);