Commit 4c7abb27 authored by Stephen Hemminger's avatar Stephen Hemminger

Merge branch 'master' into net-2.6.25

parents c1b81cb5 53c01788
...@@ -59,6 +59,10 @@ install: all ...@@ -59,6 +59,10 @@ install: all
install -m 0755 -d $(DESTDIR)$(MANDIR)/man3 install -m 0755 -d $(DESTDIR)$(MANDIR)/man3
install -m 0644 $(shell find man/man3 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man3 install -m 0644 $(shell find man/man3 -maxdepth 1 -type f) $(DESTDIR)$(MANDIR)/man3
snapshot:
echo "static const char SNAPSHOT[] = \""`date +%y%m%d`"\";" \
> include/SNAPSHOT.h
clean: clean:
rm -f cscope.* rm -f cscope.*
@for i in $(SUBDIRS) doc; \ @for i in $(SUBDIRS) doc; \
......
static char SNAPSHOT[] = "071016"; static const char SNAPSHOT[] = "071231";
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Definitions for the TCP protocol.
*
* Version: @(#)tcp.h 1.0.2 04/28/93
*
* Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* 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.
*/
#ifndef _LINUX_TCP_H
#define _LINUX_TCP_H
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/socket.h>
struct tcphdr {
__be16 source;
__be16 dest;
__be32 seq;
__be32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window;
__sum16 check;
__be16 urg_ptr;
};
/*
* The union cast uses a gcc extension to avoid aliasing problems
* (union is compatible to any of its members)
* This means this part of the code is -fstrict-aliasing safe now.
*/
union tcp_word_hdr {
struct tcphdr hdr;
__be32 words[5];
};
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
enum {
TCP_FLAG_CWR = __constant_htonl(0x00800000),
TCP_FLAG_ECE = __constant_htonl(0x00400000),
TCP_FLAG_URG = __constant_htonl(0x00200000),
TCP_FLAG_ACK = __constant_htonl(0x00100000),
TCP_FLAG_PSH = __constant_htonl(0x00080000),
TCP_FLAG_RST = __constant_htonl(0x00040000),
TCP_FLAG_SYN = __constant_htonl(0x00020000),
TCP_FLAG_FIN = __constant_htonl(0x00010000),
TCP_RESERVED_BITS = __constant_htonl(0x0F000000),
TCP_DATA_OFFSET = __constant_htonl(0xF0000000)
};
/* TCP socket options */
#define TCP_NODELAY 1 /* Turn off Nagle's algorithm. */
#define TCP_MAXSEG 2 /* Limit MSS */
#define TCP_CORK 3 /* Never send partially complete segments */
#define TCP_KEEPIDLE 4 /* Start keeplives after this period */
#define TCP_KEEPINTVL 5 /* Interval between keepalives */
#define TCP_KEEPCNT 6 /* Number of keepalives before death */
#define TCP_SYNCNT 7 /* Number of SYN retransmits */
#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
#define TCP_INFO 11 /* Information about this connection. */
#define TCP_QUICKACK 12 /* Block/reenable quick acks */
#define TCP_CONGESTION 13 /* Congestion control algorithm */
#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */
#define TCPI_OPT_TIMESTAMPS 1
#define TCPI_OPT_SACK 2
#define TCPI_OPT_WSCALE 4
#define TCPI_OPT_ECN 8
enum tcp_ca_state
{
TCP_CA_Open = 0,
#define TCPF_CA_Open (1<<TCP_CA_Open)
TCP_CA_Disorder = 1,
#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
TCP_CA_CWR = 2,
#define TCPF_CA_CWR (1<<TCP_CA_CWR)
TCP_CA_Recovery = 3,
#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
TCP_CA_Loss = 4
#define TCPF_CA_Loss (1<<TCP_CA_Loss)
};
struct tcp_info
{
__u8 tcpi_state;
__u8 tcpi_ca_state;
__u8 tcpi_retransmits;
__u8 tcpi_probes;
__u8 tcpi_backoff;
__u8 tcpi_options;
__u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
__u32 tcpi_rto;
__u32 tcpi_ato;
__u32 tcpi_snd_mss;
__u32 tcpi_rcv_mss;
__u32 tcpi_unacked;
__u32 tcpi_sacked;
__u32 tcpi_lost;
__u32 tcpi_retrans;
__u32 tcpi_fackets;
/* Times. */
__u32 tcpi_last_data_sent;
__u32 tcpi_last_ack_sent; /* Not remembered, sorry. */
__u32 tcpi_last_data_recv;
__u32 tcpi_last_ack_recv;
/* Metrics. */
__u32 tcpi_pmtu;
__u32 tcpi_rcv_ssthresh;
__u32 tcpi_rtt;
__u32 tcpi_rttvar;
__u32 tcpi_snd_ssthresh;
__u32 tcpi_snd_cwnd;
__u32 tcpi_advmss;
__u32 tcpi_reordering;
__u32 tcpi_rcv_rtt;
__u32 tcpi_rcv_space;
__u32 tcpi_total_retrans;
};
/* for TCP_MD5SIG socket option */
#define TCP_MD5SIG_MAXKEYLEN 80
struct tcp_md5sig {
struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
__u16 __tcpm_pad1; /* zero */
__u16 tcpm_keylen; /* key length */
__u32 __tcpm_pad2; /* zero */
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
};
#endif /* _LINUX_TCP_H */
#ifndef __NET_VETH_H__ #ifndef __NET_VETH_H_
#define __NET_VETH_H__ #define __NET_VETH_H_
enum { enum {
VETH_INFO_UNSPEC, VETH_INFO_UNSPEC,
VETH_INFO_MAC,
VETH_INFO_PEER, VETH_INFO_PEER,
VETH_INFO_PEER_MAC,
__VETH_INFO_MAX __VETH_INFO_MAX
#define VETH_INFO_MAX (__VETH_INFO_MAX - 1) #define VETH_INFO_MAX (__VETH_INFO_MAX - 1)
......
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Definitions for the TCP protocol sk_state field.
*
* 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.
*/
#ifndef _LINUX_TCP_STATES_H
#define _LINUX_TCP_STATES_H
enum {
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING, /* Now a valid state */
TCP_MAX_STATES /* Leave at the end! */
};
#define TCP_STATE_MASK 0xF
#define TCP_ACTION_FIN (1 << 7)
enum {
TCPF_ESTABLISHED = (1 << 1),
TCPF_SYN_SENT = (1 << 2),
TCPF_SYN_RECV = (1 << 3),
TCPF_FIN_WAIT1 = (1 << 4),
TCPF_FIN_WAIT2 = (1 << 5),
TCPF_TIME_WAIT = (1 << 6),
TCPF_CLOSE = (1 << 7),
TCPF_CLOSE_WAIT = (1 << 8),
TCPF_LAST_ACK = (1 << 9),
TCPF_LISTEN = (1 << 10),
TCPF_CLOSING = (1 << 11)
};
#endif /* _LINUX_TCP_STATES_H */
...@@ -74,6 +74,7 @@ extern int get_addr_1(inet_prefix *dst, const char *arg, int family); ...@@ -74,6 +74,7 @@ extern int get_addr_1(inet_prefix *dst, const char *arg, int family);
extern int get_prefix_1(inet_prefix *dst, char *arg, int family); extern int get_prefix_1(inet_prefix *dst, char *arg, int family);
extern int get_addr(inet_prefix *dst, const char *arg, int family); extern int get_addr(inet_prefix *dst, const char *arg, int family);
extern int get_prefix(inet_prefix *dst, char *arg, int family); extern int get_prefix(inet_prefix *dst, char *arg, int family);
extern int mask2bits(__u32 netmask);
extern int get_integer(int *val, const char *arg, int base); extern int get_integer(int *val, const char *arg, int base);
extern int get_unsigned(unsigned *val, const char *arg, int base); extern int get_unsigned(unsigned *val, const char *arg, int base);
...@@ -147,4 +148,7 @@ extern int cmdlineno; ...@@ -147,4 +148,7 @@ extern int cmdlineno;
extern ssize_t getcmdline(char **line, size_t *len, FILE *in); extern ssize_t getcmdline(char **line, size_t *len, FILE *in);
extern int makeargs(char *line, char *argv[], int maxargs); extern int makeargs(char *line, char *argv[], int maxargs);
struct iplink_req;
int iplink_parse(int argc, char **argv, struct iplink_req *req,
char **name, char **type, char **link, char **dev);
#endif /* __UTILS_H__ */ #endif /* __UTILS_H__ */
...@@ -24,3 +24,5 @@ clean: ...@@ -24,3 +24,5 @@ clean:
rm -f $(ALLOBJ) $(TARGETS) rm -f $(ALLOBJ) $(TARGETS)
LDLIBS += -ldl LDLIBS += -ldl
LDFLAGS += -Wl,-export-dynamic
...@@ -143,140 +143,159 @@ static int iplink_have_newlink(void) ...@@ -143,140 +143,159 @@ static int iplink_have_newlink(void)
} }
#endif /* ! IPLINK_IOCTL_COMPAT */ #endif /* ! IPLINK_IOCTL_COMPAT */
static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) struct iplink_req {
struct nlmsghdr n;
struct ifinfomsg i;
char buf[1024];
};
int iplink_parse(int argc, char **argv, struct iplink_req *req,
char **name, char **type, char **link, char **dev)
{ {
int ret, len;
char abuf[32];
int qlen = -1; int qlen = -1;
int mtu = -1; int mtu = -1;
int len;
char abuf[32];
char *dev = NULL;
char *name = NULL;
char *link = NULL;
char *type = NULL;
struct link_util *lu = NULL;
struct {
struct nlmsghdr n;
struct ifinfomsg i;
char buf[1024];
} req;
memset(&req, 0, sizeof(req)); ret = argc;
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
req.n.nlmsg_type = cmd;
req.i.ifi_family = preferred_family;
while (argc > 0) { while (argc > 0) {
if (strcmp(*argv, "up") == 0) { if (strcmp(*argv, "up") == 0) {
req.i.ifi_change |= IFF_UP; req->i.ifi_change |= IFF_UP;
req.i.ifi_flags |= IFF_UP; req->i.ifi_flags |= IFF_UP;
} else if (strcmp(*argv, "down") == 0) { } else if (strcmp(*argv, "down") == 0) {
req.i.ifi_change |= IFF_UP; req->i.ifi_change |= IFF_UP;
req.i.ifi_flags &= ~IFF_UP; req->i.ifi_flags &= ~IFF_UP;
} else if (strcmp(*argv, "name") == 0) { } else if (strcmp(*argv, "name") == 0) {
NEXT_ARG(); NEXT_ARG();
name = *argv; *name = *argv;
} else if (matches(*argv, "link") == 0) { } else if (matches(*argv, "link") == 0) {
NEXT_ARG(); NEXT_ARG();
link = *argv; *link = *argv;
} else if (matches(*argv, "address") == 0) { } else if (matches(*argv, "address") == 0) {
NEXT_ARG(); NEXT_ARG();
len = ll_addr_a2n(abuf, sizeof(abuf), *argv); len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
addattr_l(&req.n, sizeof(req), IFLA_ADDRESS, abuf, len); addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len);
} else if (matches(*argv, "broadcast") == 0 || } else if (matches(*argv, "broadcast") == 0 ||
strcmp(*argv, "brd") == 0) { strcmp(*argv, "brd") == 0) {
NEXT_ARG(); NEXT_ARG();
len = ll_addr_a2n(abuf, sizeof(abuf), *argv); len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
addattr_l(&req.n, sizeof(req), IFLA_BROADCAST, abuf, len); addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len);
} else if (matches(*argv, "txqueuelen") == 0 || } else if (matches(*argv, "txqueuelen") == 0 ||
strcmp(*argv, "qlen") == 0 || strcmp(*argv, "qlen") == 0 ||
matches(*argv, "txqlen") == 0) { matches(*argv, "txqlen") == 0) {
NEXT_ARG(); NEXT_ARG();
if (qlen != -1) if (qlen != -1)
duparg("txqueuelen", *argv); duparg("txqueuelen", *argv);
if (get_integer(&qlen, *argv, 0)) if (get_integer(&qlen, *argv, 0))
invarg("Invalid \"txqueuelen\" value\n", *argv); invarg("Invalid \"txqueuelen\" value\n", *argv);
addattr_l(&req.n, sizeof(req), IFLA_TXQLEN, &qlen, 4); addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4);
} else if (strcmp(*argv, "mtu") == 0) { } else if (strcmp(*argv, "mtu") == 0) {
NEXT_ARG(); NEXT_ARG();
if (mtu != -1) if (mtu != -1)
duparg("mtu", *argv); duparg("mtu", *argv);
if (get_integer(&mtu, *argv, 0)) if (get_integer(&mtu, *argv, 0))
invarg("Invalid \"mtu\" value\n", *argv); invarg("Invalid \"mtu\" value\n", *argv);
addattr_l(&req.n, sizeof(req), IFLA_MTU, &mtu, 4); addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
} else if (strcmp(*argv, "multicast") == 0) { } else if (strcmp(*argv, "multicast") == 0) {
NEXT_ARG(); NEXT_ARG();
req.i.ifi_change |= IFF_MULTICAST; req->i.ifi_change |= IFF_MULTICAST;
if (strcmp(*argv, "on") == 0) { if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_MULTICAST; req->i.ifi_flags |= IFF_MULTICAST;
} else if (strcmp(*argv, "off") == 0) { } else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_MULTICAST; req->i.ifi_flags &= ~IFF_MULTICAST;
} else } else
return on_off("multicast"); return on_off("multicast");
} else if (strcmp(*argv, "allmulticast") == 0) { } else if (strcmp(*argv, "allmulticast") == 0) {
NEXT_ARG(); NEXT_ARG();
req.i.ifi_change |= IFF_ALLMULTI; req->i.ifi_change |= IFF_ALLMULTI;
if (strcmp(*argv, "on") == 0) { if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_ALLMULTI; req->i.ifi_flags |= IFF_ALLMULTI;
} else if (strcmp(*argv, "off") == 0) { } else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_ALLMULTI; req->i.ifi_flags &= ~IFF_ALLMULTI;
} else } else
return on_off("allmulticast"); return on_off("allmulticast");
} else if (strcmp(*argv, "promisc") == 0) { } else if (strcmp(*argv, "promisc") == 0) {
NEXT_ARG(); NEXT_ARG();
req.i.ifi_change |= IFF_PROMISC; req->i.ifi_change |= IFF_PROMISC;
if (strcmp(*argv, "on") == 0) { if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_PROMISC; req->i.ifi_flags |= IFF_PROMISC;
} else if (strcmp(*argv, "off") == 0) { } else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_PROMISC; req->i.ifi_flags &= ~IFF_PROMISC;
} else } else
return on_off("promisc"); return on_off("promisc");
} else if (strcmp(*argv, "trailers") == 0) { } else if (strcmp(*argv, "trailers") == 0) {
NEXT_ARG(); NEXT_ARG();
req.i.ifi_change |= IFF_NOTRAILERS; req->i.ifi_change |= IFF_NOTRAILERS;
if (strcmp(*argv, "off") == 0) { if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags |= IFF_NOTRAILERS; req->i.ifi_flags |= IFF_NOTRAILERS;
} else if (strcmp(*argv, "on") == 0) { } else if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags &= ~IFF_NOTRAILERS; req->i.ifi_flags &= ~IFF_NOTRAILERS;
} else } else
return on_off("trailers"); return on_off("trailers");
} else if (strcmp(*argv, "arp") == 0) { } else if (strcmp(*argv, "arp") == 0) {
NEXT_ARG(); NEXT_ARG();
req.i.ifi_change |= IFF_NOARP; req->i.ifi_change |= IFF_NOARP;
if (strcmp(*argv, "on") == 0) { if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags &= ~IFF_NOARP; req->i.ifi_flags &= ~IFF_NOARP;
} else if (strcmp(*argv, "off") == 0) { } else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags |= IFF_NOARP; req->i.ifi_flags |= IFF_NOARP;
} else } else
return on_off("noarp"); return on_off("noarp");
#ifdef IFF_DYNAMIC #ifdef IFF_DYNAMIC
} else if (matches(*argv, "dynamic") == 0) { } else if (matches(*argv, "dynamic") == 0) {
NEXT_ARG(); NEXT_ARG();
req.i.ifi_change |= IFF_DYNAMIC; req->i.ifi_change |= IFF_DYNAMIC;
if (strcmp(*argv, "on") == 0) { if (strcmp(*argv, "on") == 0) {
req.i.ifi_flags |= IFF_DYNAMIC; req->i.ifi_flags |= IFF_DYNAMIC;
} else if (strcmp(*argv, "off") == 0) { } else if (strcmp(*argv, "off") == 0) {
req.i.ifi_flags &= ~IFF_DYNAMIC; req->i.ifi_flags &= ~IFF_DYNAMIC;
} else } else
return on_off("dynamic"); return on_off("dynamic");
#endif #endif
} else if (matches(*argv, "type") == 0) { } else if (matches(*argv, "type") == 0) {
NEXT_ARG(); NEXT_ARG();
type = *argv; *type = *argv;
argc--; argv++; argc--; argv++;
break; break;
} else { } else {
if (strcmp(*argv, "dev") == 0) { if (strcmp(*argv, "dev") == 0) {
NEXT_ARG(); NEXT_ARG();
} }
if (dev) if (*dev)
duparg2("dev", *argv); duparg2("dev", *argv);
dev = *argv; *dev = *argv;
} }
argc--; argv++; argc--; argv++;
} }
return ret - argc;
}
static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
{
int len;
char *dev = NULL;
char *name = NULL;
char *link = NULL;
char *type = NULL;
struct link_util *lu = NULL;
struct iplink_req req;
int ret;
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
req.n.nlmsg_type = cmd;
req.i.ifi_family = preferred_family;
ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev);
if (ret < 0)
return ret;
argc -= ret;
argv += ret;
ll_init_map(&rth); ll_init_map(&rth);
if (type) { if (type) {
......
...@@ -509,7 +509,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -509,7 +509,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
i != RTAX_RTO_MIN) i != RTAX_RTO_MIN)
fprintf(fp, " %u", *(unsigned*)RTA_DATA(mxrta[i])); fprintf(fp, " %u", *(unsigned*)RTA_DATA(mxrta[i]));
else { else {
unsigned val = *(unsigned*)RTA_DATA(mxrta[i]); unsigned long long val = *(unsigned*)RTA_DATA(mxrta[i]);
val *= 1000; val *= 1000;
if (i == RTAX_RTT) if (i == RTAX_RTT)
...@@ -517,7 +517,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -517,7 +517,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
else if (i == RTAX_RTTVAR) else if (i == RTAX_RTTVAR)
val /= 4; val /= 4;
if (val >= hz) if (val >= hz)
fprintf(fp, " %ums", val/hz); fprintf(fp, " %llums", val/hz);
else else
fprintf(fp, " %.2fms", (float)val/hz); fprintf(fp, " %.2fms", (float)val/hz);
} }
......
...@@ -10,78 +10,51 @@ ...@@ -10,78 +10,51 @@
* *
*/ */
#include <stdio.h>
#include <string.h> #include <string.h>
#include <net/if.h>
#include <linux/veth.h>
#include "utils.h" #include "utils.h"
#include "ip_common.h" #include "ip_common.h"
#include "veth.h"
#define ETH_ALEN 6
static void usage(void) static void usage(void)
{ {
printf("Usage: ip link add ... type veth " printf("Usage: ip link <options> type veth "
"[peer <peer-name>] [mac <mac>] [peer_mac <mac>]\n"); "[peer <options>]\nTo get <options> type "
"'ip link add help'\n");
} }
static int veth_parse_opt(struct link_util *lu, int argc, char **argv, static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *hdr) struct nlmsghdr *hdr)
{ {
__u8 mac[ETH_ALEN]; char *name, *type, *link, *dev;
int err, len;
for (; argc != 0; argv++, argc--) { struct rtattr * data;
if (strcmp(*argv, "peer") == 0) {
argv++;
argc--;
if (argc == 0) {
usage();
return -1;
}
addattr_l(hdr, 1024, VETH_INFO_PEER,
*argv, strlen(*argv));
continue;
}
if (strcmp(*argv, "mac") == 0) {
argv++;
argc--;
if (argc == 0) {
usage();
return -1;
}
if (hexstring_a2n(*argv, mac, sizeof(mac)) == NULL)
return -1;
addattr_l(hdr, 1024, VETH_INFO_MAC, if (strcmp(argv[0], "peer") != 0) {
mac, ETH_ALEN); usage();
continue; return -1;
} }
if (strcmp(*argv, "peer_mac") == 0) { data = NLMSG_TAIL(hdr);
argv++; addattr_l(hdr, 1024, VETH_INFO_PEER, NULL, 0);
argc--;
if (argc == 0) {
usage();
return -1;
}
if (hexstring_a2n(*argv, mac, sizeof(mac)) == NULL) hdr->nlmsg_len += sizeof(struct ifinfomsg);
return -1;
addattr_l(hdr, 1024, VETH_INFO_PEER_MAC, err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr,
mac, ETH_ALEN); &name, &type, &link, &dev);
continue; if (err < 0)
} return err;
usage(); if (name) {
return -1; len = strlen(name) + 1;
if (len > IFNAMSIZ)
invarg("\"name\" too long\n", *argv);
addattr_l(hdr, 1024, IFLA_IFNAME, name, len);
} }
return 0; data->rta_len = (void *)NLMSG_TAIL(hdr) - (void *)data;
return argc - 1 - err;
} }
struct link_util veth_link_util = { struct link_util veth_link_util = {
......
...@@ -47,27 +47,18 @@ int get_integer(int *val, const char *arg, int base) ...@@ -47,27 +47,18 @@ int get_integer(int *val, const char *arg, int base)
return 0; return 0;
} }
/* a valid netmask must be 2^n - 1 */ int mask2bits(__u32 netmask)
static int is_valid_netmask(const inet_prefix *addr)
{
uint32_t host;
if (addr->family != AF_INET)
return 0;
host = ~ntohl(addr->data[0]);
return (host & (host + 1)) == 0;
}
static unsigned cidr(const inet_prefix *addr)
{ {
unsigned bits = 0; unsigned bits = 0;
u_int32_t mask; __u32 mask = ntohl(netmask);
__u32 host = ~mask;
for (mask = ntohl(addr->data[0]); mask; mask <<= 1) /* a valid netmask must be 2^n - 1 */
++bits; if ((host & (host + 1)) != 0)
return -1;
for (; mask; mask <<= 1)
++bits;
return bits; return bits;
} }
...@@ -79,11 +70,13 @@ static int get_netmask(unsigned *val, const char *arg, int base) ...@@ -79,11 +70,13 @@ static int get_netmask(unsigned *val, const char *arg, int base)
return 0; return 0;
/* try coverting dotted quad to CIDR */ /* try coverting dotted quad to CIDR */
if (!get_addr_1(&addr, arg, AF_INET)) { if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) {
if (is_valid_netmask(&addr)) int b = mask2bits(addr.data[0]);
if (b >= 0) {
*val = b;
return 0; return 0;
}
*val = cidr(&addr);
} }
return -1; return -1;
......
...@@ -32,7 +32,7 @@ maddr " | " mroute " | " monitor " }" ...@@ -32,7 +32,7 @@ maddr " | " mroute " | " monitor " }"
.br .br
.BR promisc " { " on " | " off " } |" .BR promisc " { " on " | " off " } |"
.br .br
.BR allmulti " { " on " | " off " } |" .BR allmulticast " { " on " | " off " } |"
.br .br
.BR dynamic " { " on " | " off " } |" .BR dynamic " { " on " | " off " } |"
.br .br
......
...@@ -107,7 +107,7 @@ Display all UDP sockets. ...@@ -107,7 +107,7 @@ Display all UDP sockets.
.B ss -o state established '( dport = :ssh or sport = :ssh )' .B ss -o state established '( dport = :ssh or sport = :ssh )'
Display all established ssh connections. Display all established ssh connections.
.TP .TP
.B ss -x src \"/tmp/.X11-unix/*\" .B ss -x src /tmp/.X11-unix/*
Find all local processes connected to X server. Find all local processes connected to X server.
.TP .TP
.B ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24 .B ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24
......
...@@ -33,9 +33,8 @@ ...@@ -33,9 +33,8 @@
#include "libnetlink.h" #include "libnetlink.h"
#include "SNAPSHOT.h" #include "SNAPSHOT.h"
#include <netinet/tcp.h>
#include <linux/inet_diag.h> #include <linux/inet_diag.h>
#include <linux/tcp.h>
#include <net/tcp_states.h>
int resolve_hosts = 0; int resolve_hosts = 0;
int resolve_services = 1; int resolve_services = 1;
......
...@@ -473,7 +473,7 @@ done: ...@@ -473,7 +473,7 @@ done:
*argv_p = argv; *argv_p = argv;
return res; return res;
} }
static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) static int parse_ip6(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
{ {
int res = -1; int res = -1;
...@@ -564,6 +564,7 @@ done: ...@@ -564,6 +564,7 @@ done:
return res; return res;
} }
static int parse_icmp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) static int parse_icmp(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
{ {
int res = -1; int res = -1;
...@@ -771,7 +772,47 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) ...@@ -771,7 +772,47 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
return 0; return 0;
} }
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n) static void show_key(FILE *f, const struct tc_u32_key *key)
{
char abuf[256];
if (show_raw)
goto raw;
switch (key->off) {
case 12:
case 16: {
int bits = mask2bits(key->mask);
if (bits >= 0) {
fprintf(f, "\n %s %s/%d\n",
key->off == 12 ? "src" : "dst",
inet_ntop(AF_INET, &key->val, abuf, sizeof(abuf)),
bits);
return;
}
}
break;
case 20:
case 22:
if (key->mask == ntohl(0xffff)) {
fprintf(f, "\n %s %u\n",
key->off == 20 ? "sport" : "dport",
(unsigned short) ntohl(key->val));
return;
}
}
raw:
fprintf(f, "\n match %08x/%08x at %s%d",
(unsigned int)ntohl(key->val),
(unsigned int)ntohl(key->mask),
key->offmask ? "nexthdr+" : "",
key->off);
}
static int u32_parse_opt(struct filter_util *qu, char *handle,
int argc, char **argv, struct nlmsghdr *n)
{ {
struct { struct {
struct tc_u32_sel sel; struct tc_u32_sel sel;
...@@ -966,7 +1007,8 @@ static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char ** ...@@ -966,7 +1007,8 @@ static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **
return 0; return 0;
} }
static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u32 handle) static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
__u32 handle)
{ {
struct rtattr *tb[TCA_U32_MAX+1]; struct rtattr *tb[TCA_U32_MAX+1];
struct tc_u32_sel *sel = NULL; struct tc_u32_sel *sel = NULL;
...@@ -1037,17 +1079,12 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __ ...@@ -1037,17 +1079,12 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt, __
} }
if (sel) { if (sel) {
int i;
struct tc_u32_key *key = sel->keys;
if (sel->nkeys) { if (sel->nkeys) {
for (i=0; i<sel->nkeys; i++, key++) { int i;
fprintf(f, "\n match %08x/%08x at %s%d", for (i=0; i<sel->nkeys; i++) {
(unsigned int)ntohl(key->val), show_key(f, sel->keys + i);
(unsigned int)ntohl(key->mask),
key->offmask ? "nexthdr+" : "",
key->off);
if (show_stats && NULL != pf) if (show_stats && NULL != pf)
fprintf(f, " (success %lld ) ", fprintf(f, " (success %llu ) ",
(unsigned long long) pf->kcnts[i]); (unsigned long long) pf->kcnts[i]);
} }
} }
......
...@@ -69,6 +69,13 @@ register_target(struct iptables_target *me) ...@@ -69,6 +69,13 @@ register_target(struct iptables_target *me)
} }
void
xtables_register_target(struct iptables_target *me)
{
me->next = t_list;
t_list = me;
}
void void
exit_tryhelp(int status) exit_tryhelp(int status)
{ {
...@@ -249,11 +256,24 @@ get_target_name(const char *name) ...@@ -249,11 +256,24 @@ get_target_name(const char *name)
} }
} }
sprintf(path, "%s/libipt_%s.so",lib_dir, new_name); /* try libxt_xx first */
sprintf(path, "%s/libxt_%s.so", lib_dir, new_name);
handle = dlopen(path, RTLD_LAZY); handle = dlopen(path, RTLD_LAZY);
if (!handle) { if (!handle) {
sprintf(path, lib_dir, "/libipt_%s.so", lname); /* try libipt_xx next */
sprintf(path, "%s/libipt_%s.so", lib_dir, new_name);
handle = dlopen(path, RTLD_LAZY); handle = dlopen(path, RTLD_LAZY);
if (!handle) {
sprintf(path, "%s/libxt_%s.so", lib_dir , lname);
handle = dlopen(path, RTLD_LAZY);
}
if (!handle) {
sprintf(path, "%s/libipt_%s.so", lib_dir , lname);
handle = dlopen(path, RTLD_LAZY);
}
/* ok, lets give up .. */
if (!handle) { if (!handle) {
fputs(dlerror(), stderr); fputs(dlerror(), stderr);
printf("\n"); printf("\n");
......
...@@ -263,22 +263,20 @@ int act_parse_police(struct action_util *a,int *argc_p, char ***argv_p, int tca_ ...@@ -263,22 +263,20 @@ int act_parse_police(struct action_util *a,int *argc_p, char ***argv_p, int tca_
} }
if (p.rate.rate) { if (p.rate.rate) {
if ((Rcell_log = tc_calc_rtable(p.rate.rate, rtab, Rcell_log, mtu, mpu)) < 0) { p.rate.mpu = mpu;
if (tc_calc_rtable(&p.rate, rtab, Rcell_log, mtu) < 0) {
fprintf(stderr, "TBF: failed to calculate rate table.\n"); fprintf(stderr, "TBF: failed to calculate rate table.\n");
return -1; return -1;
} }
p.burst = tc_calc_xmittime(p.rate.rate, buffer); p.burst = tc_calc_xmittime(p.rate.rate, buffer);
p.rate.cell_log = Rcell_log;
p.rate.mpu = mpu;
} }
p.mtu = mtu; p.mtu = mtu;
if (p.peakrate.rate) { if (p.peakrate.rate) {
if ((Pcell_log = tc_calc_rtable(p.peakrate.rate, ptab, Pcell_log, mtu, mpu)) < 0) { p.peakrate.mpu = mpu;
if (tc_calc_rtable(&p.peakrate, ptab, Pcell_log, mtu) < 0) {
fprintf(stderr, "POLICE: failed to calculate peak rate table.\n"); fprintf(stderr, "POLICE: failed to calculate peak rate table.\n");
return -1; return -1;
} }
p.peakrate.cell_log = Pcell_log;
p.peakrate.mpu = mpu;
} }
tail = NLMSG_TAIL(n); tail = NLMSG_TAIL(n);
......
...@@ -137,12 +137,11 @@ static int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl ...@@ -137,12 +137,11 @@ static int cbq_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
if (allot < (avpkt*3)/2) if (allot < (avpkt*3)/2)
allot = (avpkt*3)/2; allot = (avpkt*3)/2;
if ((cell_log = tc_calc_rtable(r.rate, rtab, cell_log, allot, mpu)) < 0) { r.mpu = mpu;
if (tc_calc_rtable(&r, rtab, cell_log, allot) < 0) {
fprintf(stderr, "CBQ: failed to calculate rate table.\n"); fprintf(stderr, "CBQ: failed to calculate rate table.\n");
return -1; return -1;
} }
r.cell_log = cell_log;
r.mpu = mpu;
if (ewma_log < 0) if (ewma_log < 0)
ewma_log = TC_CBQ_DEF_EWMA; ewma_log = TC_CBQ_DEF_EWMA;
...@@ -336,12 +335,11 @@ static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str ...@@ -336,12 +335,11 @@ static int cbq_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
unsigned pktsize = wrr.allot; unsigned pktsize = wrr.allot;
if (wrr.allot < (lss.avpkt*3)/2) if (wrr.allot < (lss.avpkt*3)/2)
wrr.allot = (lss.avpkt*3)/2; wrr.allot = (lss.avpkt*3)/2;
if ((cell_log = tc_calc_rtable(r.rate, rtab, cell_log, pktsize, mpu)) < 0) { r.mpu = mpu;
if (tc_calc_rtable(&r, rtab, cell_log, pktsize) < 0) {
fprintf(stderr, "CBQ: failed to calculate rate table.\n"); fprintf(stderr, "CBQ: failed to calculate rate table.\n");
return -1; return -1;
} }
r.cell_log = cell_log;
r.mpu = mpu;
} }
if (ewma_log < 0) if (ewma_log < 0)
ewma_log = TC_CBQ_DEF_EWMA; ewma_log = TC_CBQ_DEF_EWMA;
......
...@@ -107,8 +107,9 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str ...@@ -107,8 +107,9 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
__u32 rtab[256],ctab[256]; __u32 rtab[256],ctab[256];
unsigned buffer=0,cbuffer=0; unsigned buffer=0,cbuffer=0;
int cell_log=-1,ccell_log = -1; int cell_log=-1,ccell_log = -1;
unsigned mtu, mpu; unsigned mtu;
unsigned char mpu8 = 0, overhead = 0; unsigned short mpu = 0;
unsigned short overhead = 0;
struct rtattr *tail; struct rtattr *tail;
memset(&opt, 0, sizeof(opt)); mtu = 1600; /* eth packet len */ memset(&opt, 0, sizeof(opt)); mtu = 1600; /* eth packet len */
...@@ -127,12 +128,12 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str ...@@ -127,12 +128,12 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
} }
} else if (matches(*argv, "mpu") == 0) { } else if (matches(*argv, "mpu") == 0) {
NEXT_ARG(); NEXT_ARG();
if (get_u8(&mpu8, *argv, 10)) { if (get_u16(&mpu, *argv, 10)) {
explain1("mpu"); return -1; explain1("mpu"); return -1;
} }
} else if (matches(*argv, "overhead") == 0) { } else if (matches(*argv, "overhead") == 0) {
NEXT_ARG(); NEXT_ARG();
if (get_u8(&overhead, *argv, 10)) { if (get_u16(&overhead, *argv, 10)) {
explain1("overhead"); return -1; explain1("overhead"); return -1;
} }
} else if (matches(*argv, "quantum") == 0) { } else if (matches(*argv, "quantum") == 0) {
...@@ -206,23 +207,23 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str ...@@ -206,23 +207,23 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
if (!buffer) buffer = opt.rate.rate / get_hz() + mtu; if (!buffer) buffer = opt.rate.rate / get_hz() + mtu;
if (!cbuffer) cbuffer = opt.ceil.rate / get_hz() + mtu; if (!cbuffer) cbuffer = opt.ceil.rate / get_hz() + mtu;
/* encode overhead and mpu, 8 bits each, into lower 16 bits */ opt.ceil.overhead = overhead;
mpu = (unsigned)mpu8 | (unsigned)overhead << 8; opt.rate.overhead = overhead;
opt.ceil.mpu = mpu; opt.rate.mpu = mpu;
if ((cell_log = tc_calc_rtable(opt.rate.rate, rtab, cell_log, mtu, mpu)) < 0) { opt.ceil.mpu = mpu;
opt.rate.mpu = mpu;
if (tc_calc_rtable(&opt.rate, rtab, cell_log, mtu) < 0) {
fprintf(stderr, "htb: failed to calculate rate table.\n"); fprintf(stderr, "htb: failed to calculate rate table.\n");
return -1; return -1;
} }
opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer); opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer);
opt.rate.cell_log = cell_log;
if ((ccell_log = tc_calc_rtable(opt.ceil.rate, ctab, cell_log, mtu, mpu)) < 0) { if (tc_calc_rtable(&opt.ceil, ctab, ccell_log, mtu) < 0) {
fprintf(stderr, "htb: failed to calculate ceil rate table.\n"); fprintf(stderr, "htb: failed to calculate ceil rate table.\n");
return -1; return -1;
} }
opt.cbuffer = tc_calc_xmittime(opt.ceil.rate, cbuffer); opt.cbuffer = tc_calc_xmittime(opt.ceil.rate, cbuffer);
opt.ceil.cell_log = ccell_log;
tail = NLMSG_TAIL(n); tail = NLMSG_TAIL(n);
addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
......
...@@ -170,21 +170,20 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl ...@@ -170,21 +170,20 @@ static int tbf_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct nl
opt.limit = lim; opt.limit = lim;
} }
if ((Rcell_log = tc_calc_rtable(opt.rate.rate, rtab, Rcell_log, mtu, mpu)) < 0) { opt.rate.mpu = mpu;
if (tc_calc_rtable(&opt.rate, rtab, Rcell_log, mtu) < 0) {
fprintf(stderr, "TBF: failed to calculate rate table.\n"); fprintf(stderr, "TBF: failed to calculate rate table.\n");
return -1; return -1;
} }
opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer); opt.buffer = tc_calc_xmittime(opt.rate.rate, buffer);
opt.rate.cell_log = Rcell_log;
opt.rate.mpu = mpu;
if (opt.peakrate.rate) { if (opt.peakrate.rate) {
if ((Pcell_log = tc_calc_rtable(opt.peakrate.rate, ptab, Pcell_log, mtu, mpu)) < 0) { opt.peakrate.mpu = mpu;
if (tc_calc_rtable(&opt.peakrate, ptab, Pcell_log, mtu) < 0) {
fprintf(stderr, "TBF: failed to calculate peak rate table.\n"); fprintf(stderr, "TBF: failed to calculate peak rate table.\n");
return -1; return -1;
} }
opt.mtu = tc_calc_xmittime(opt.peakrate.rate, mtu); opt.mtu = tc_calc_xmittime(opt.peakrate.rate, mtu);
opt.peakrate.cell_log = Pcell_log;
opt.peakrate.mpu = mpu;
} }
tail = NLMSG_TAIL(n); tail = NLMSG_TAIL(n);
......
...@@ -69,12 +69,11 @@ unsigned tc_calc_xmitsize(unsigned rate, unsigned ticks) ...@@ -69,12 +69,11 @@ unsigned tc_calc_xmitsize(unsigned rate, unsigned ticks)
rtab[pkt_len>>cell_log] = pkt_xmit_time rtab[pkt_len>>cell_log] = pkt_xmit_time
*/ */
int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, int tc_calc_rtable(struct tc_ratespec *r, __u32 *rtab, int cell_log, unsigned mtu)
unsigned mpu)
{ {
int i; int i;
unsigned overhead = (mpu >> 8) & 0xFF; unsigned bps = r->rate;
mpu = mpu & 0xFF; unsigned mpu = r->mpu;
if (mtu == 0) if (mtu == 0)
mtu = 2047; mtu = 2047;
...@@ -85,13 +84,13 @@ int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, ...@@ -85,13 +84,13 @@ int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu,
cell_log++; cell_log++;
} }
for (i=0; i<256; i++) { for (i=0; i<256; i++) {
unsigned sz = (i<<cell_log); unsigned sz = ((i+1)<<cell_log);
if (overhead)
sz += overhead;
if (sz < mpu) if (sz < mpu)
sz = mpu; sz = mpu;
rtab[i] = tc_calc_xmittime(bps, sz); rtab[i] = tc_calc_xmittime(bps, sz);
} }
r->cell_align=-1; // Due to the sz calc
r->cell_log=cell_log;
return cell_log; return cell_log;
} }
......
...@@ -13,7 +13,7 @@ unsigned tc_core_time2ktime(unsigned time); ...@@ -13,7 +13,7 @@ unsigned tc_core_time2ktime(unsigned time);
unsigned tc_core_ktime2time(unsigned ktime); unsigned tc_core_ktime2time(unsigned ktime);
unsigned tc_calc_xmittime(unsigned rate, unsigned size); unsigned tc_calc_xmittime(unsigned rate, unsigned size);
unsigned tc_calc_xmitsize(unsigned rate, unsigned ticks); unsigned tc_calc_xmitsize(unsigned rate, unsigned ticks);
int tc_calc_rtable(unsigned bps, __u32 *rtab, int cell_log, unsigned mtu, unsigned mpu); int tc_calc_rtable(struct tc_ratespec *r, __u32 *rtab, int cell_log, unsigned mtu);
int tc_setup_estimator(unsigned A, unsigned time_const, struct tc_estimator *est); int tc_setup_estimator(unsigned A, unsigned time_const, struct tc_estimator *est);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment