Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2
This commit is contained in:
commit
f63bb3e4ad
1
Makefile
1
Makefile
|
|
@ -56,6 +56,7 @@ install: all
|
||||||
ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/rtstat.8
|
ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/rtstat.8
|
||||||
ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/ctstat.8
|
ln -sf lnstat.8 $(DESTDIR)$(MANDIR)/man8/ctstat.8
|
||||||
ln -sf rtacct.8 $(DESTDIR)$(MANDIR)/man8/nstat.8
|
ln -sf rtacct.8 $(DESTDIR)$(MANDIR)/man8/nstat.8
|
||||||
|
ln -sf routel.8 $(DESTDIR)$(MANDIR)/man8/routef.8
|
||||||
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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,10 @@ broadcast address will break networking.
|
||||||
Do not use it, if you do not understand what this operation really does.
|
Do not use it, if you do not understand what this operation really does.
|
||||||
\end{NB}
|
\end{NB}
|
||||||
|
|
||||||
|
\item \verb|netns PID|
|
||||||
|
|
||||||
|
--- move the device to the network namespace associated with the process PID.
|
||||||
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
\vskip 1mm
|
\vskip 1mm
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include <linux/atmapi.h>
|
#include <linux/atmapi.h>
|
||||||
#include <linux/atmsap.h>
|
#include <linux/atmsap.h>
|
||||||
#include <linux/atmioc.h>
|
#include <linux/atmioc.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
|
||||||
/* general ATM constants */
|
/* general ATM constants */
|
||||||
|
|
@ -207,7 +208,7 @@ struct sockaddr_atmsvc {
|
||||||
char pub[ATM_E164_LEN+1]; /* public address (E.164) */
|
char pub[ATM_E164_LEN+1]; /* public address (E.164) */
|
||||||
/* unused addresses must be bzero'ed */
|
/* unused addresses must be bzero'ed */
|
||||||
char lij_type; /* role in LIJ call; one of ATM_LIJ* */
|
char lij_type; /* role in LIJ call; one of ATM_LIJ* */
|
||||||
uint32_t lij_id; /* LIJ call identifier */
|
__u32 lij_id; /* LIJ call identifier */
|
||||||
} sas_addr __ATM_API_ALIGN; /* SVC address */
|
} sas_addr __ATM_API_ALIGN; /* SVC address */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
|
#define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1)
|
||||||
#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
|
#define SIOCDELTUNNEL (SIOCDEVPRIVATE + 2)
|
||||||
#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
|
#define SIOCCHGTUNNEL (SIOCDEVPRIVATE + 3)
|
||||||
|
#define SIOCGETPRL (SIOCDEVPRIVATE + 4)
|
||||||
|
#define SIOCADDPRL (SIOCDEVPRIVATE + 5)
|
||||||
|
#define SIOCDELPRL (SIOCDEVPRIVATE + 6)
|
||||||
|
#define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
|
||||||
|
|
||||||
#define GRE_CSUM __constant_htons(0x8000)
|
#define GRE_CSUM __constant_htons(0x8000)
|
||||||
#define GRE_ROUTING __constant_htons(0x4000)
|
#define GRE_ROUTING __constant_htons(0x4000)
|
||||||
|
|
@ -17,9 +21,6 @@
|
||||||
#define GRE_FLAGS __constant_htons(0x00F8)
|
#define GRE_FLAGS __constant_htons(0x00F8)
|
||||||
#define GRE_VERSION __constant_htons(0x0007)
|
#define GRE_VERSION __constant_htons(0x0007)
|
||||||
|
|
||||||
/* i_flags values for SIT mode */
|
|
||||||
#define SIT_ISATAP 0x0001
|
|
||||||
|
|
||||||
struct ip_tunnel_parm
|
struct ip_tunnel_parm
|
||||||
{
|
{
|
||||||
char name[IFNAMSIZ];
|
char name[IFNAMSIZ];
|
||||||
|
|
@ -31,4 +32,19 @@ struct ip_tunnel_parm
|
||||||
struct iphdr iph;
|
struct iphdr iph;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* SIT-mode i_flags */
|
||||||
|
#define SIT_ISATAP 0x0001
|
||||||
|
|
||||||
|
struct ip_tunnel_prl {
|
||||||
|
__be32 addr;
|
||||||
|
__u16 flags;
|
||||||
|
__u16 __reserved;
|
||||||
|
__u32 datalen;
|
||||||
|
__u32 __reserved2;
|
||||||
|
/* data follows */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PRL flags */
|
||||||
|
#define PRL_DEFAULT 0x0001
|
||||||
|
|
||||||
#endif /* _IF_TUNNEL_H_ */
|
#endif /* _IF_TUNNEL_H_ */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __LINUX_NETFILTER_H
|
#ifndef __LINUX_NETFILTER_H
|
||||||
#define __LINUX_NETFILTER_H
|
#define __LINUX_NETFILTER_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
/* Responses from hook functions. */
|
/* Responses from hook functions. */
|
||||||
#define NF_DROP 0
|
#define NF_DROP 0
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,6 @@ enum nf_ip_hook_priorities {
|
||||||
NF_IP_PRI_FILTER = 0,
|
NF_IP_PRI_FILTER = 0,
|
||||||
NF_IP_PRI_NAT_SRC = 100,
|
NF_IP_PRI_NAT_SRC = 100,
|
||||||
NF_IP_PRI_SELINUX_LAST = 225,
|
NF_IP_PRI_SELINUX_LAST = 225,
|
||||||
NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2,
|
|
||||||
NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1,
|
|
||||||
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
|
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
|
||||||
NF_IP_PRI_LAST = INT_MAX,
|
NF_IP_PRI_LAST = INT_MAX,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,7 @@ enum rt_class_t
|
||||||
{
|
{
|
||||||
RT_TABLE_UNSPEC=0,
|
RT_TABLE_UNSPEC=0,
|
||||||
/* User defined values */
|
/* User defined values */
|
||||||
|
RT_TABLE_COMPAT=252,
|
||||||
RT_TABLE_DEFAULT=253,
|
RT_TABLE_DEFAULT=253,
|
||||||
RT_TABLE_MAIN=254,
|
RT_TABLE_MAIN=254,
|
||||||
RT_TABLE_LOCAL=255,
|
RT_TABLE_LOCAL=255,
|
||||||
|
|
@ -267,10 +268,10 @@ enum rtattr_type_t
|
||||||
RTA_PREFSRC,
|
RTA_PREFSRC,
|
||||||
RTA_METRICS,
|
RTA_METRICS,
|
||||||
RTA_MULTIPATH,
|
RTA_MULTIPATH,
|
||||||
RTA_PROTOINFO,
|
RTA_PROTOINFO, /* no longer used */
|
||||||
RTA_FLOW,
|
RTA_FLOW,
|
||||||
RTA_CACHEINFO,
|
RTA_CACHEINFO,
|
||||||
RTA_SESSION,
|
RTA_SESSION, /* no longer used */
|
||||||
RTA_MP_ALGO, /* no longer used */
|
RTA_MP_ALGO, /* no longer used */
|
||||||
RTA_TABLE,
|
RTA_TABLE,
|
||||||
__RTA_MAX
|
__RTA_MAX
|
||||||
|
|
|
||||||
|
|
@ -162,11 +162,4 @@ typedef __u16 __bitwise __sum16;
|
||||||
typedef __u32 __bitwise __wsum;
|
typedef __u32 __bitwise __wsum;
|
||||||
|
|
||||||
|
|
||||||
struct ustat {
|
|
||||||
__kernel_daddr_t f_tfree;
|
|
||||||
__kernel_ino_t f_tinode;
|
|
||||||
char f_fname[6];
|
|
||||||
char f_fpack[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _LINUX_TYPES_H */
|
#endif /* _LINUX_TYPES_H */
|
||||||
|
|
|
||||||
|
|
@ -97,10 +97,10 @@ struct xfrm_algo {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xfrm_algo_aead {
|
struct xfrm_algo_aead {
|
||||||
char alg_name[64];
|
char alg_name[64];
|
||||||
int alg_key_len; /* in bits */
|
unsigned int alg_key_len; /* in bits */
|
||||||
int alg_icv_len; /* in bits */
|
unsigned int alg_icv_len; /* in bits */
|
||||||
char alg_key[0];
|
char alg_key[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xfrm_stats {
|
struct xfrm_stats {
|
||||||
|
|
@ -113,7 +113,8 @@ enum
|
||||||
{
|
{
|
||||||
XFRM_POLICY_TYPE_MAIN = 0,
|
XFRM_POLICY_TYPE_MAIN = 0,
|
||||||
XFRM_POLICY_TYPE_SUB = 1,
|
XFRM_POLICY_TYPE_SUB = 1,
|
||||||
XFRM_POLICY_TYPE_MAX = 2
|
XFRM_POLICY_TYPE_MAX = 2,
|
||||||
|
XFRM_POLICY_TYPE_ANY = 255
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ void iplink_usage(void)
|
||||||
fprintf(stderr, " name NEWNAME |\n");
|
fprintf(stderr, " name NEWNAME |\n");
|
||||||
fprintf(stderr, " address LLADDR | broadcast LLADDR |\n");
|
fprintf(stderr, " address LLADDR | broadcast LLADDR |\n");
|
||||||
fprintf(stderr, " mtu MTU }\n");
|
fprintf(stderr, " mtu MTU }\n");
|
||||||
|
fprintf(stderr, " netns PID }\n");
|
||||||
fprintf(stderr, " ip link show [ DEVICE ]\n");
|
fprintf(stderr, " ip link show [ DEVICE ]\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
@ -156,6 +157,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
||||||
char abuf[32];
|
char abuf[32];
|
||||||
int qlen = -1;
|
int qlen = -1;
|
||||||
int mtu = -1;
|
int mtu = -1;
|
||||||
|
int netns = -1;
|
||||||
|
|
||||||
ret = argc;
|
ret = argc;
|
||||||
|
|
||||||
|
|
@ -197,6 +199,13 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
|
||||||
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, "netns") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (netns != -1)
|
||||||
|
duparg("netns", *argv);
|
||||||
|
if (get_integer(&netns, *argv, 0))
|
||||||
|
invarg("Invalid \"netns\" value\n", *argv);
|
||||||
|
addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 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;
|
||||||
|
|
|
||||||
|
|
@ -272,10 +272,9 @@ int print_neigh(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
||||||
fprintf(fp, " router");
|
fprintf(fp, " router");
|
||||||
}
|
}
|
||||||
if (tb[NDA_CACHEINFO] && show_stats) {
|
if (tb[NDA_CACHEINFO] && show_stats) {
|
||||||
static int hz;
|
|
||||||
struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
|
struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
|
||||||
if (!hz)
|
int hz = get_user_hz();
|
||||||
hz = get_hz();
|
|
||||||
if (ci->ndm_refcnt)
|
if (ci->ndm_refcnt)
|
||||||
printf(" ref %d", ci->ndm_refcnt);
|
printf(" ref %d", ci->ndm_refcnt);
|
||||||
fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,
|
fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,8 @@ static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ XFRM_OPT ] [ mode MODE ]\n");
|
fprintf(stderr, "Usage: ip xfrm state { add | update } ID [ XFRM_OPT ] [ mode MODE ]\n");
|
||||||
fprintf(stderr, " [ reqid REQID ] [ seq SEQ ] [ replay-window SIZE ] [ flag FLAG-LIST ]\n");
|
fprintf(stderr, " [ reqid REQID ] [ seq SEQ ] [ replay-window SIZE ] [ flag FLAG-LIST ]\n");
|
||||||
fprintf(stderr, " [ encap ENCAP ] [ sel SELECTOR ] [ LIMIT-LIST ]\n");
|
fprintf(stderr, " [ encap ENCAP ] [ sel SELECTOR ] [ replay-seq SEQ ]\n");
|
||||||
|
fprintf(stderr, " [ replay-oseq SEQ ] [ LIMIT-LIST ]\n");
|
||||||
fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ reqid REQID ] [ seq SEQ ]\n");
|
fprintf(stderr, "Usage: ip xfrm state allocspi ID [ mode MODE ] [ reqid REQID ] [ seq SEQ ]\n");
|
||||||
fprintf(stderr, " [ min SPI max SPI ]\n");
|
fprintf(stderr, " [ min SPI max SPI ]\n");
|
||||||
fprintf(stderr, "Usage: ip xfrm state { delete | get } ID\n");
|
fprintf(stderr, "Usage: ip xfrm state { delete | get } ID\n");
|
||||||
|
|
@ -232,6 +233,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
|
||||||
struct xfrm_usersa_info xsinfo;
|
struct xfrm_usersa_info xsinfo;
|
||||||
char buf[RTA_BUF_SIZE];
|
char buf[RTA_BUF_SIZE];
|
||||||
} req;
|
} req;
|
||||||
|
struct xfrm_replay_state replay;
|
||||||
char *idp = NULL;
|
char *idp = NULL;
|
||||||
char *ealgop = NULL;
|
char *ealgop = NULL;
|
||||||
char *aalgop = NULL;
|
char *aalgop = NULL;
|
||||||
|
|
@ -239,6 +241,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
|
||||||
char *coap = NULL;
|
char *coap = NULL;
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
|
memset(&replay, 0, sizeof(replay));
|
||||||
|
|
||||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo));
|
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo));
|
||||||
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
|
req.n.nlmsg_flags = NLM_F_REQUEST|flags;
|
||||||
|
|
@ -264,6 +267,14 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
if (get_u8(&req.xsinfo.replay_window, *argv, 0))
|
if (get_u8(&req.xsinfo.replay_window, *argv, 0))
|
||||||
invarg("\"replay-window\" value is invalid", *argv);
|
invarg("\"replay-window\" value is invalid", *argv);
|
||||||
|
} else if (strcmp(*argv, "replay-seq") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (get_u32(&replay.seq, *argv, 0))
|
||||||
|
invarg("\"replay-seq\" value is invalid", *argv);
|
||||||
|
} else if (strcmp(*argv, "replay-oseq") == 0) {
|
||||||
|
NEXT_ARG();
|
||||||
|
if (get_u32(&replay.oseq, *argv, 0))
|
||||||
|
invarg("\"replay-oseq\" value is invalid", *argv);
|
||||||
} else if (strcmp(*argv, "flag") == 0) {
|
} else if (strcmp(*argv, "flag") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
xfrm_state_flag_parse(&req.xsinfo.flags, &argc, &argv);
|
xfrm_state_flag_parse(&req.xsinfo.flags, &argc, &argv);
|
||||||
|
|
@ -386,6 +397,10 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (replay.seq || replay.oseq)
|
||||||
|
addattr_l(&req.n, sizeof(req.buf), XFRMA_REPLAY_VAL,
|
||||||
|
(void *)&replay, sizeof(replay));
|
||||||
|
|
||||||
if (!idp) {
|
if (!idp) {
|
||||||
fprintf(stderr, "Not enough information: \"ID\" is required\n");
|
fprintf(stderr, "Not enough information: \"ID\" is required\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
||||||
27
lib/utils.c
27
lib/utils.c
|
|
@ -246,10 +246,6 @@ int get_s8(__s8 *val, const char *arg, int base)
|
||||||
|
|
||||||
int get_addr_1(inet_prefix *addr, const char *name, int family)
|
int get_addr_1(inet_prefix *addr, const char *name, int family)
|
||||||
{
|
{
|
||||||
const char *cp;
|
|
||||||
unsigned char *ap = (unsigned char*)addr->data;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(addr, 0, sizeof(*addr));
|
memset(addr, 0, sizeof(*addr));
|
||||||
|
|
||||||
if (strcmp(name, "default") == 0 ||
|
if (strcmp(name, "default") == 0 ||
|
||||||
|
|
@ -288,17 +284,10 @@ int get_addr_1(inet_prefix *addr, const char *name, int family)
|
||||||
addr->family = AF_INET;
|
addr->family = AF_INET;
|
||||||
if (family != AF_UNSPEC && family != AF_INET)
|
if (family != AF_UNSPEC && family != AF_INET)
|
||||||
return -1;
|
return -1;
|
||||||
|
if (inet_pton(AF_INET, name, addr->data) <= 0)
|
||||||
|
return -1;
|
||||||
addr->bytelen = 4;
|
addr->bytelen = 4;
|
||||||
addr->bitlen = -1;
|
addr->bitlen = -1;
|
||||||
for (cp=name, i=0; *cp; cp++) {
|
|
||||||
if (*cp <= '9' && *cp >= '0') {
|
|
||||||
ap[i] = 10*ap[i] + (*cp-'0');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (*cp == '.' && ++i <= 3)
|
|
||||||
continue;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -518,13 +507,14 @@ const char *rt_addr_n2a(int af, int len, const void *addr, char *buf, int buflen
|
||||||
struct namerec
|
struct namerec
|
||||||
{
|
{
|
||||||
struct namerec *next;
|
struct namerec *next;
|
||||||
|
const char *name;
|
||||||
inet_prefix addr;
|
inet_prefix addr;
|
||||||
char *name;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct namerec *nht[256];
|
#define NHASH 257
|
||||||
|
static struct namerec *nht[NHASH];
|
||||||
|
|
||||||
char *resolve_address(const char *addr, int len, int af)
|
static const char *resolve_address(const void *addr, int len, int af)
|
||||||
{
|
{
|
||||||
struct namerec *n;
|
struct namerec *n;
|
||||||
struct hostent *h_ent;
|
struct hostent *h_ent;
|
||||||
|
|
@ -539,7 +529,7 @@ char *resolve_address(const char *addr, int len, int af)
|
||||||
len = 4;
|
len = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = addr[len-1] ^ addr[len-2] ^ addr[len-3] ^ addr[len-4];
|
hash = *(__u32 *)(addr + len - 4) % NHASH;
|
||||||
|
|
||||||
for (n = nht[hash]; n; n = n->next) {
|
for (n = nht[hash]; n; n = n->next) {
|
||||||
if (n->addr.family == af &&
|
if (n->addr.family == af &&
|
||||||
|
|
@ -573,7 +563,8 @@ const char *format_host(int af, int len, const void *addr,
|
||||||
{
|
{
|
||||||
#ifdef RESOLVE_HOSTNAMES
|
#ifdef RESOLVE_HOSTNAMES
|
||||||
if (resolve_hosts) {
|
if (resolve_hosts) {
|
||||||
char *n;
|
const char *n;
|
||||||
|
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
switch (af) {
|
switch (af) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,10 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
|
||||||
.IR LLADDR " |"
|
.IR LLADDR " |"
|
||||||
.br
|
.br
|
||||||
.B mtu
|
.B mtu
|
||||||
.IR MTU " }"
|
.IR MTU " |"
|
||||||
|
.br
|
||||||
|
.B netns
|
||||||
|
.IR PID " }"
|
||||||
|
|
||||||
.ti -8
|
.ti -8
|
||||||
.B ip link show
|
.B ip link show
|
||||||
|
|
@ -873,6 +876,11 @@ change the link layer broadcast address or the peer address when
|
||||||
the interface is
|
the interface is
|
||||||
.IR "POINTOPOINT" .
|
.IR "POINTOPOINT" .
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BI netns " PID"
|
||||||
|
move the device to the network namespace associated with the process
|
||||||
|
.IR "PID" .
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
.B Warning:
|
.B Warning:
|
||||||
If multiple parameter changes are requested,
|
If multiple parameter changes are requested,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
.TH "ROUTEL" "8" "3 Jan, 2008" "iproute2" "Linux"
|
||||||
|
.SH "NAME"
|
||||||
|
.LP
|
||||||
|
routel \- list routes with pretty output format
|
||||||
|
.br
|
||||||
|
routef \- flush routes
|
||||||
|
.SH "SYNTAX"
|
||||||
|
.LP
|
||||||
|
routel [\fItablenr\fP [\fIraw ip args...\fP]]
|
||||||
|
.br
|
||||||
|
routef
|
||||||
|
.SH "DESCRIPTION"
|
||||||
|
.LP
|
||||||
|
These programs are a set of helper scripts you can use instead of raw iproute2 commands.
|
||||||
|
.br
|
||||||
|
The routel script will list routes in a format that some might consider easier to interpret then the ip route list equivalent.
|
||||||
|
.br
|
||||||
|
The routef script does not take any arguments and will simply flush the routing table down the drain. Beware! This means deleting all routes which will make your network unusable!
|
||||||
|
|
||||||
|
.SH "FILES"
|
||||||
|
.LP
|
||||||
|
\fI/usr/bin/routef\fP
|
||||||
|
.br
|
||||||
|
\fI/usr/bin/routel\fP
|
||||||
|
.SH "AUTHORS"
|
||||||
|
.LP
|
||||||
|
The routel script was written by Stephen R. van den Berg <srb@cuci.nl>, 1999/04/18 and donated to the public domain.
|
||||||
|
.br
|
||||||
|
This manual page was written by Andreas Henriksson <andreas@fatal.se>, for the Debian GNU/Linux system.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.LP
|
||||||
|
ip(8)
|
||||||
|
|
@ -34,16 +34,28 @@ priority filtertype
|
||||||
.B flowid
|
.B flowid
|
||||||
flow-id
|
flow-id
|
||||||
|
|
||||||
.B tc [-s | -d ] qdisc show [ dev
|
.B tc
|
||||||
|
.RI "[ " FORMAT " ]"
|
||||||
|
.B qdisc show [ dev
|
||||||
DEV
|
DEV
|
||||||
.B ]
|
.B ]
|
||||||
.P
|
.P
|
||||||
.B tc [-s | -d ] class show dev
|
.B tc
|
||||||
|
.RI "[ " FORMAT " ]"
|
||||||
|
.B class show dev
|
||||||
DEV
|
DEV
|
||||||
.P
|
.P
|
||||||
.B tc filter show dev
|
.B tc filter show dev
|
||||||
DEV
|
DEV
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.IR FORMAT " := {"
|
||||||
|
\fB\-s\fR[\fItatistics\fR] |
|
||||||
|
\fB\-d\fR[\fIetails\fR] |
|
||||||
|
\fB\-r\fR[\fIaw\fR] |
|
||||||
|
\fB\-p\fR[\fIretty\fR] |
|
||||||
|
\fB\i\fR[\fIec\fR] }
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B Tc
|
.B Tc
|
||||||
is used to configure Traffic Control in the Linux kernel. Traffic Control consists
|
is used to configure Traffic Control in the Linux kernel. Traffic Control consists
|
||||||
|
|
@ -326,6 +338,29 @@ link
|
||||||
Only available for qdiscs and performs a replace where the node
|
Only available for qdiscs and performs a replace where the node
|
||||||
must exist already.
|
must exist already.
|
||||||
|
|
||||||
|
.SH FORMAT
|
||||||
|
The show command has additional formatting options:
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-s" , " \-stats", " \-statistics"
|
||||||
|
output more statistics about packet usage.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-d", " \-details"
|
||||||
|
output more detailed information about rates and cell sizes.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-r", " \-raw"
|
||||||
|
output raw hex values for handles.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-p", " \-pretty"
|
||||||
|
decode filter offset and mask values to equivalent filter commands based on TCP/IP.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR "\-iec"
|
||||||
|
print rates in IEC units (ie. 1K = 1024).
|
||||||
|
|
||||||
|
|
||||||
.SH HISTORY
|
.SH HISTORY
|
||||||
.B tc
|
.B tc
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Maximum number of fields that can be displayed */
|
/* Maximum number of fields that can be displayed */
|
||||||
#define MAX_FIELDS 64
|
#define MAX_FIELDS 128
|
||||||
|
|
||||||
/* Maximum number of header lines */
|
/* Maximum number of header lines */
|
||||||
#define HDR_LINES 10
|
#define HDR_LINES 10
|
||||||
|
|
@ -121,9 +121,17 @@ static int map_field_params(struct lnstat_file *lnstat_files,
|
||||||
if (!fps->params[j].print.width)
|
if (!fps->params[j].print.width)
|
||||||
fps->params[j].print.width =
|
fps->params[j].print.width =
|
||||||
FIELD_WIDTH_DEFAULT;
|
FIELD_WIDTH_DEFAULT;
|
||||||
j++;
|
|
||||||
|
if (++j >= MAX_FIELDS - 1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARN: MAX_FIELDS (%d) reached,"
|
||||||
|
" truncating number of keys\n",
|
||||||
|
MAX_FIELDS);
|
||||||
|
goto full;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
full:
|
||||||
fps->num = j;
|
fps->num = j;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -269,8 +277,13 @@ int main(int argc, char **argv)
|
||||||
for (tok = strtok(tmp, ",");
|
for (tok = strtok(tmp, ",");
|
||||||
tok;
|
tok;
|
||||||
tok = strtok(NULL, ",")) {
|
tok = strtok(NULL, ",")) {
|
||||||
if (fp.num >= MAX_FIELDS)
|
if (fp.num >= MAX_FIELDS) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"WARN: too many keys"
|
||||||
|
" requested: (%d max)\n",
|
||||||
|
MAX_FIELDS);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
fp.params[fp.num++].name = tok;
|
fp.params[fp.num++].name = tok;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ int npatterns;
|
||||||
char info_source[128];
|
char info_source[128];
|
||||||
int source_mismatch;
|
int source_mismatch;
|
||||||
|
|
||||||
int generic_proc_open(char *env, char *name)
|
static int generic_proc_open(const char *env, char *name)
|
||||||
{
|
{
|
||||||
char store[128];
|
char store[128];
|
||||||
char *p = getenv(env);
|
char *p = getenv(env);
|
||||||
|
|
@ -52,7 +52,7 @@ int generic_proc_open(char *env, char *name)
|
||||||
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
||||||
p = store;
|
p = store;
|
||||||
}
|
}
|
||||||
return open(store, O_RDONLY);
|
return open(p, O_RDONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_netstat_open(void)
|
int net_netstat_open(void)
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ int dump_zeros = 0;
|
||||||
unsigned long magic_number = 0;
|
unsigned long magic_number = 0;
|
||||||
double W;
|
double W;
|
||||||
|
|
||||||
int generic_proc_open(char *env, char *name)
|
static int generic_proc_open(const char *env, const char *name)
|
||||||
{
|
{
|
||||||
char store[1024];
|
char store[1024];
|
||||||
char *p = getenv(env);
|
char *p = getenv(env);
|
||||||
|
|
@ -52,7 +52,7 @@ int generic_proc_open(char *env, char *name)
|
||||||
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
snprintf(store, sizeof(store)-1, "%s/%s", p, name);
|
||||||
p = store;
|
p = store;
|
||||||
}
|
}
|
||||||
return open(store, O_RDONLY);
|
return open(p, O_RDONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
int net_rtacct_open(void)
|
int net_rtacct_open(void)
|
||||||
|
|
|
||||||
|
|
@ -420,7 +420,7 @@ const char *print_ms_timer(int timeout)
|
||||||
|
|
||||||
const char *print_hz_timer(int timeout)
|
const char *print_hz_timer(int timeout)
|
||||||
{
|
{
|
||||||
int hz = get_hz();
|
int hz = get_user_hz();
|
||||||
return print_ms_timer(((timeout*1000) + hz-1)/hz);
|
return print_ms_timer(((timeout*1000) + hz-1)/hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1191,10 +1191,11 @@ static int tcp_show_line(char *line, const struct filter *f, int family)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (show_tcpinfo) {
|
if (show_tcpinfo) {
|
||||||
if (s.rto && s.rto != 3*get_hz())
|
int hz = get_user_hz();
|
||||||
printf(" rto:%g", (double)s.rto/get_hz());
|
if (s.rto && s.rto != 3*hz)
|
||||||
|
printf(" rto:%g", (double)s.rto/hz);
|
||||||
if (s.ato)
|
if (s.ato)
|
||||||
printf(" ato:%g", (double)s.ato/get_hz());
|
printf(" ato:%g", (double)s.ato/hz);
|
||||||
if (s.cwnd != 2)
|
if (s.cwnd != 2)
|
||||||
printf(" cwnd:%d", s.cwnd);
|
printf(" cwnd:%d", s.cwnd);
|
||||||
if (s.ssthresh != -1)
|
if (s.ssthresh != -1)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ DISTGEN = maketable normal pareto paretonormal
|
||||||
DISTDATA = normal.dist pareto.dist paretonormal.dist experimental.dist
|
DISTDATA = normal.dist pareto.dist paretonormal.dist experimental.dist
|
||||||
|
|
||||||
HOSTCC ?= $(CC)
|
HOSTCC ?= $(CC)
|
||||||
|
CCOPTS = $(CBUILD_CFLAGS)
|
||||||
LDLIBS += -lm
|
LDLIBS += -lm
|
||||||
|
|
||||||
all: $(DISTGEN) $(DISTDATA)
|
all: $(DISTGEN) $(DISTDATA)
|
||||||
|
|
|
||||||
61
tc/f_u32.c
61
tc/f_u32.c
|
|
@ -21,10 +21,13 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "tc_util.h"
|
#include "tc_util.h"
|
||||||
|
|
||||||
|
extern int show_pretty;
|
||||||
|
|
||||||
static void explain(void)
|
static void explain(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: ... u32 [ match SELECTOR ... ] [ link HTID ]"
|
fprintf(stderr, "Usage: ... u32 [ match SELECTOR ... ] [ link HTID ]"
|
||||||
|
|
@ -789,27 +792,24 @@ static int parse_hashkey(int *argc_p, char ***argv_p, struct tc_u32_sel *sel)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_key(FILE *f, const struct tc_u32_key *key)
|
static void print_ipv4(FILE *f, const struct tc_u32_key *key)
|
||||||
{
|
{
|
||||||
char abuf[256];
|
char abuf[256];
|
||||||
|
|
||||||
if (show_raw)
|
|
||||||
goto raw;
|
|
||||||
|
|
||||||
switch (key->off) {
|
switch (key->off) {
|
||||||
case 0:
|
case 0:
|
||||||
switch (ntohl(key->mask)) {
|
switch (ntohl(key->mask)) {
|
||||||
case 0x0f000000:
|
case 0x0f000000:
|
||||||
fprintf(f, "\n ihl %u", ntohl(key->val) >> 24);
|
fprintf(f, "\n match IP ihl %u", ntohl(key->val) >> 24);
|
||||||
return;
|
return;
|
||||||
case 0x00ff0000:
|
case 0x00ff0000:
|
||||||
fprintf(f, "\n dsfield %#x", ntohl(key->val) >> 16);
|
fprintf(f, "\n match IP dsfield %#x", ntohl(key->val) >> 16);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if (ntohl(key->mask) == 0x00ff0000) {
|
if (ntohl(key->mask) == 0x00ff0000) {
|
||||||
fprintf(f, "\n protocol %u", ntohl(key->val) >> 16);
|
fprintf(f, "\n match IP protocol %d", ntohl(key->val) >> 16);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -818,7 +818,7 @@ static void show_key(FILE *f, const struct tc_u32_key *key)
|
||||||
int bits = mask2bits(key->mask);
|
int bits = mask2bits(key->mask);
|
||||||
if (bits >= 0) {
|
if (bits >= 0) {
|
||||||
fprintf(f, "\n %s %s/%d",
|
fprintf(f, "\n %s %s/%d",
|
||||||
key->off == 12 ? "src" : "dst",
|
key->off == 12 ? "match IP src" : "match IP dst",
|
||||||
inet_ntop(AF_INET, &key->val,
|
inet_ntop(AF_INET, &key->val,
|
||||||
abuf, sizeof(abuf)),
|
abuf, sizeof(abuf)),
|
||||||
bits);
|
bits);
|
||||||
|
|
@ -830,31 +830,62 @@ static void show_key(FILE *f, const struct tc_u32_key *key)
|
||||||
case 20:
|
case 20:
|
||||||
switch (ntohl(key->mask)) {
|
switch (ntohl(key->mask)) {
|
||||||
case 0x0000ffff:
|
case 0x0000ffff:
|
||||||
fprintf(f, "\n sport %u",
|
fprintf(f, "\n match sport %u",
|
||||||
ntohl(key->val) & 0xffff);
|
ntohl(key->val) & 0xffff);
|
||||||
return;
|
return;
|
||||||
case 0xffff0000:
|
case 0xffff0000:
|
||||||
fprintf(f, "\n dport %u",
|
fprintf(f, "\n match dport %u",
|
||||||
ntohl(key->val) >> 16);
|
ntohl(key->val) >> 16);
|
||||||
return;
|
return;
|
||||||
case 0xffffffff:
|
case 0xffffffff:
|
||||||
fprintf(f, "\n sport %u, dport %u",
|
fprintf(f, "\n match sport %u, match dport %u",
|
||||||
ntohl(key->val) & 0xffff,
|
ntohl(key->val) & 0xffff,
|
||||||
ntohl(key->val) >> 16);
|
ntohl(key->val) >> 16);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* XXX: Default print_raw */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
raw:
|
static void print_raw(FILE *f, const struct tc_u32_key *key)
|
||||||
fprintf(f, "\n match %08x/%08x at %s%d",
|
{
|
||||||
|
fprintf(f, "\n match %08x/%08x at %s%d",
|
||||||
(unsigned int)ntohl(key->val),
|
(unsigned int)ntohl(key->val),
|
||||||
(unsigned int)ntohl(key->mask),
|
(unsigned int)ntohl(key->mask),
|
||||||
key->offmask ? "nexthdr+" : "",
|
key->offmask ? "nexthdr+" : "",
|
||||||
key->off);
|
key->off);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u32_parse_opt(struct filter_util *qu, char *handle,
|
static const struct {
|
||||||
|
__u16 proto;
|
||||||
|
__u16 pad;
|
||||||
|
void (*pprinter)(FILE *f, const struct tc_u32_key *key);
|
||||||
|
} u32_pprinters[] = {
|
||||||
|
{0, 0, print_raw},
|
||||||
|
{ETH_P_IP, 0, print_ipv4},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void show_keys(FILE *f, const struct tc_u32_key *key)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (!show_pretty)
|
||||||
|
goto show_k;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(u32_pprinters) / sizeof(u32_pprinters[0]); i++) {
|
||||||
|
if (u32_pprinters[i].proto == ntohs(f_proto)) {
|
||||||
|
show_k:
|
||||||
|
u32_pprinters[i].pprinter(f, key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
goto show_k;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int u32_parse_opt(struct filter_util *qu, char *handle,
|
||||||
int argc, char **argv, struct nlmsghdr *n)
|
int argc, char **argv, struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -1129,7 +1160,7 @@ static int u32_print_opt(struct filter_util *qu, FILE *f, struct rtattr *opt,
|
||||||
if (sel->nkeys) {
|
if (sel->nkeys) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<sel->nkeys; i++) {
|
for (i=0; i<sel->nkeys; i++) {
|
||||||
show_key(f, sel->keys + i);
|
show_keys(f, sel->keys + i);
|
||||||
if (show_stats && NULL != pf)
|
if (show_stats && NULL != pf)
|
||||||
fprintf(f, " (success %llu ) ",
|
fprintf(f, " (success %llu ) ",
|
||||||
(unsigned long long) pf->kcnts[i]);
|
(unsigned long long) pf->kcnts[i]);
|
||||||
|
|
|
||||||
|
|
@ -491,3 +491,80 @@ int print_ematch(FILE *fd, const struct rtattr *rta)
|
||||||
|
|
||||||
return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]);
|
return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct bstr * bstr_alloc(const char *text)
|
||||||
|
{
|
||||||
|
struct bstr *b = calloc(1, sizeof(*b));
|
||||||
|
|
||||||
|
if (b == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
b->data = strdup(text);
|
||||||
|
if (b->data == NULL) {
|
||||||
|
free(b);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
b->len = strlen(text);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long bstrtoul(const struct bstr *b)
|
||||||
|
{
|
||||||
|
char *inv = NULL;
|
||||||
|
unsigned long l;
|
||||||
|
char buf[b->len+1];
|
||||||
|
|
||||||
|
memcpy(buf, b->data, b->len);
|
||||||
|
buf[b->len] = '\0';
|
||||||
|
|
||||||
|
l = strtoul(buf, &inv, 0);
|
||||||
|
if (l == ULONG_MAX || inv == buf)
|
||||||
|
return ULONG_MAX;
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bstr_print(FILE *fd, const struct bstr *b, int ascii)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *s = b->data;
|
||||||
|
|
||||||
|
if (ascii)
|
||||||
|
for (i = 0; i < b->len; i++)
|
||||||
|
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
|
||||||
|
else {
|
||||||
|
for (i = 0; i < b->len; i++)
|
||||||
|
fprintf(fd, "%02x", s[i]);
|
||||||
|
fprintf(fd, "\"");
|
||||||
|
for (i = 0; i < b->len; i++)
|
||||||
|
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
|
||||||
|
fprintf(fd, "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_ematch_tree(const struct ematch *tree)
|
||||||
|
{
|
||||||
|
const struct ematch *t;
|
||||||
|
|
||||||
|
for (t = tree; t; t = t->next) {
|
||||||
|
if (t->inverted)
|
||||||
|
printf("NOT ");
|
||||||
|
|
||||||
|
if (t->child) {
|
||||||
|
printf("(");
|
||||||
|
print_ematch_tree(t->child);
|
||||||
|
printf(")");
|
||||||
|
} else {
|
||||||
|
struct bstr *b;
|
||||||
|
for (b = t->args; b; b = b->next)
|
||||||
|
printf("%s%s", b->data, b->next ? " " : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->relation == TCF_EM_REL_AND)
|
||||||
|
printf(" AND ");
|
||||||
|
else if (t->relation == TCF_EM_REL_OR)
|
||||||
|
printf(" OR ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,23 +18,7 @@ struct bstr
|
||||||
struct bstr *next;
|
struct bstr *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct bstr * bstr_alloc(const char *text)
|
extern struct bstr * bstr_alloc(const char *text);
|
||||||
{
|
|
||||||
struct bstr *b = calloc(1, sizeof(*b));
|
|
||||||
|
|
||||||
if (b == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
b->data = strdup(text);
|
|
||||||
if (b->data == NULL) {
|
|
||||||
free(b);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
b->len = strlen(text);
|
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct bstr * bstr_new(char *data, unsigned int len)
|
static inline struct bstr * bstr_new(char *data, unsigned int len)
|
||||||
{
|
{
|
||||||
|
|
@ -60,45 +44,15 @@ static inline int bstrcmp(struct bstr *b, const char *text)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long bstrtoul(struct bstr *b)
|
|
||||||
{
|
|
||||||
char *inv = NULL;
|
|
||||||
unsigned long l;
|
|
||||||
char buf[b->len+1];
|
|
||||||
|
|
||||||
memcpy(buf, b->data, b->len);
|
|
||||||
buf[b->len] = '\0';
|
|
||||||
|
|
||||||
l = strtol(buf, &inv, 0);
|
|
||||||
if (l == ULONG_MAX || inv == buf)
|
|
||||||
return LONG_MAX;
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bstr_print(FILE *fd, struct bstr *b, int ascii)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *s = b->data;
|
|
||||||
|
|
||||||
if (ascii)
|
|
||||||
for (i = 0; i < b->len; i++)
|
|
||||||
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
|
|
||||||
else {
|
|
||||||
for (i = 0; i < b->len; i++)
|
|
||||||
fprintf(fd, "%02x", s[i]);
|
|
||||||
fprintf(fd, "\"");
|
|
||||||
for (i = 0; i < b->len; i++)
|
|
||||||
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
|
|
||||||
fprintf(fd, "\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct bstr *bstr_next(struct bstr *b)
|
static inline struct bstr *bstr_next(struct bstr *b)
|
||||||
{
|
{
|
||||||
return b->next;
|
return b->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern unsigned long bstrtoul(const struct bstr *b);
|
||||||
|
extern void bstr_print(FILE *fd, const struct bstr *b, int ascii);
|
||||||
|
|
||||||
|
|
||||||
struct ematch
|
struct ematch
|
||||||
{
|
{
|
||||||
struct bstr *args;
|
struct bstr *args;
|
||||||
|
|
@ -123,30 +77,8 @@ static inline struct ematch * new_ematch(struct bstr *args, int inverted)
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void print_ematch_tree(struct ematch *tree)
|
extern void print_ematch_tree(const struct ematch *tree);
|
||||||
{
|
|
||||||
struct ematch *t;
|
|
||||||
|
|
||||||
for (t = tree; t; t = t->next) {
|
|
||||||
if (t->inverted)
|
|
||||||
printf("NOT ");
|
|
||||||
|
|
||||||
if (t->child) {
|
|
||||||
printf("(");
|
|
||||||
print_ematch_tree(t->child);
|
|
||||||
printf(")");
|
|
||||||
} else {
|
|
||||||
struct bstr *b;
|
|
||||||
for (b = t->args; b; b = b->next)
|
|
||||||
printf("%s%s", b->data, b->next ? " " : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t->relation == TCF_EM_REL_AND)
|
|
||||||
printf(" AND ");
|
|
||||||
else if (t->relation == TCF_EM_REL_OR)
|
|
||||||
printf(" OR ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ematch_util
|
struct ematch_util
|
||||||
{
|
{
|
||||||
|
|
|
||||||
6
tc/tc.c
6
tc/tc.c
|
|
@ -33,6 +33,8 @@
|
||||||
int show_stats = 0;
|
int show_stats = 0;
|
||||||
int show_details = 0;
|
int show_details = 0;
|
||||||
int show_raw = 0;
|
int show_raw = 0;
|
||||||
|
int show_pretty = 0;
|
||||||
|
|
||||||
int resolve_hosts = 0;
|
int resolve_hosts = 0;
|
||||||
int use_iec = 0;
|
int use_iec = 0;
|
||||||
int force = 0;
|
int force = 0;
|
||||||
|
|
@ -182,7 +184,7 @@ static void usage(void)
|
||||||
fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
|
fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
|
||||||
" tc [-force] -batch file\n"
|
" tc [-force] -batch file\n"
|
||||||
"where OBJECT := { qdisc | class | filter | action | monitor }\n"
|
"where OBJECT := { qdisc | class | filter | action | monitor }\n"
|
||||||
" OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -b[atch] [file] }\n");
|
" OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [file] }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_cmd(int argc, char **argv)
|
static int do_cmd(int argc, char **argv)
|
||||||
|
|
@ -273,6 +275,8 @@ int main(int argc, char **argv)
|
||||||
++show_details;
|
++show_details;
|
||||||
} else if (matches(argv[1], "-raw") == 0) {
|
} else if (matches(argv[1], "-raw") == 0) {
|
||||||
++show_raw;
|
++show_raw;
|
||||||
|
} else if (matches(argv[1], "-pretty") == 0) {
|
||||||
|
++show_pretty;
|
||||||
} else if (matches(argv[1], "-Version") == 0) {
|
} else if (matches(argv[1], "-Version") == 0) {
|
||||||
printf("tc utility, iproute2-ss%s\n", SNAPSHOT);
|
printf("tc utility, iproute2-ss%s\n", SNAPSHOT);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv)
|
||||||
} req;
|
} req;
|
||||||
struct filter_util *q = NULL;
|
struct filter_util *q = NULL;
|
||||||
__u32 prio = 0;
|
__u32 prio = 0;
|
||||||
__u32 protocol = ETH_P_ALL;
|
__u32 protocol = 0;
|
||||||
int protocol_set = 0;
|
int protocol_set = 0;
|
||||||
char *fhandle = NULL;
|
char *fhandle = NULL;
|
||||||
char d[16];
|
char d[16];
|
||||||
|
|
@ -72,6 +72,9 @@ int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv)
|
||||||
req.n.nlmsg_type = cmd;
|
req.n.nlmsg_type = cmd;
|
||||||
req.t.tcm_family = AF_UNSPEC;
|
req.t.tcm_family = AF_UNSPEC;
|
||||||
|
|
||||||
|
if (cmd == RTM_NEWTFILTER && flags & NLM_F_CREATE)
|
||||||
|
protocol = ETH_P_ALL;
|
||||||
|
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
if (strcmp(*argv, "dev") == 0) {
|
if (strcmp(*argv, "dev") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
|
|
@ -175,6 +178,7 @@ static __u32 filter_parent;
|
||||||
static int filter_ifindex;
|
static int filter_ifindex;
|
||||||
static __u32 filter_prio;
|
static __u32 filter_prio;
|
||||||
static __u32 filter_protocol;
|
static __u32 filter_protocol;
|
||||||
|
__u16 f_proto = 0;
|
||||||
|
|
||||||
int print_filter(const struct sockaddr_nl *who,
|
int print_filter(const struct sockaddr_nl *who,
|
||||||
struct nlmsghdr *n,
|
struct nlmsghdr *n,
|
||||||
|
|
@ -221,13 +225,13 @@ int print_filter(const struct sockaddr_nl *who,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (t->tcm_info) {
|
if (t->tcm_info) {
|
||||||
__u32 protocol = TC_H_MIN(t->tcm_info);
|
f_proto = TC_H_MIN(t->tcm_info);
|
||||||
__u32 prio = TC_H_MAJ(t->tcm_info)>>16;
|
__u32 prio = TC_H_MAJ(t->tcm_info)>>16;
|
||||||
if (!filter_protocol || filter_protocol != protocol) {
|
if (!filter_protocol || filter_protocol != f_proto) {
|
||||||
if (protocol) {
|
if (f_proto) {
|
||||||
SPRINT_BUF(b1);
|
SPRINT_BUF(b1);
|
||||||
fprintf(fp, "protocol %s ",
|
fprintf(fp, "protocol %s ",
|
||||||
ll_proto_n2a(protocol, b1, sizeof(b1)));
|
ll_proto_n2a(f_proto, b1, sizeof(b1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!filter_prio || filter_prio != prio) {
|
if (!filter_prio || filter_prio != prio) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ struct qdisc_util
|
||||||
int (*print_copt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
|
int (*print_copt)(struct qdisc_util *qu, FILE *f, struct rtattr *opt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern __u16 f_proto;
|
||||||
struct filter_util
|
struct filter_util
|
||||||
{
|
{
|
||||||
struct filter_util *next;
|
struct filter_util *next;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue