Merge branch 'net-next'

This commit is contained in:
Stephen Hemminger 2016-08-09 11:14:47 -07:00
commit 592990ebf4
20 changed files with 367 additions and 53 deletions

View File

@ -84,6 +84,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_HASH,
BPF_MAP_TYPE_PERCPU_ARRAY, BPF_MAP_TYPE_PERCPU_ARRAY,
BPF_MAP_TYPE_STACK_TRACE, BPF_MAP_TYPE_STACK_TRACE,
BPF_MAP_TYPE_CGROUP_ARRAY,
}; };
enum bpf_prog_type { enum bpf_prog_type {
@ -93,6 +94,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_SCHED_CLS, BPF_PROG_TYPE_SCHED_CLS,
BPF_PROG_TYPE_SCHED_ACT, BPF_PROG_TYPE_SCHED_ACT,
BPF_PROG_TYPE_TRACEPOINT, BPF_PROG_TYPE_TRACEPOINT,
BPF_PROG_TYPE_XDP,
}; };
#define BPF_PSEUDO_MAP_FD 1 #define BPF_PSEUDO_MAP_FD 1
@ -313,6 +315,66 @@ enum bpf_func_id {
*/ */
BPF_FUNC_skb_get_tunnel_opt, BPF_FUNC_skb_get_tunnel_opt,
BPF_FUNC_skb_set_tunnel_opt, BPF_FUNC_skb_set_tunnel_opt,
/**
* bpf_skb_change_proto(skb, proto, flags)
* Change protocol of the skb. Currently supported is
* v4 -> v6, v6 -> v4 transitions. The helper will also
* resize the skb. eBPF program is expected to fill the
* new headers via skb_store_bytes and lX_csum_replace.
* @skb: pointer to skb
* @proto: new skb->protocol type
* @flags: reserved
* Return: 0 on success or negative error
*/
BPF_FUNC_skb_change_proto,
/**
* bpf_skb_change_type(skb, type)
* Change packet type of skb.
* @skb: pointer to skb
* @type: new skb->pkt_type type
* Return: 0 on success or negative error
*/
BPF_FUNC_skb_change_type,
/**
* bpf_skb_in_cgroup(skb, map, index) - Check cgroup2 membership of skb
* @skb: pointer to skb
* @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type
* @index: index of the cgroup in the bpf_map
* Return:
* == 0 skb failed the cgroup2 descendant test
* == 1 skb succeeded the cgroup2 descendant test
* < 0 error
*/
BPF_FUNC_skb_in_cgroup,
/**
* bpf_get_hash_recalc(skb)
* Retrieve and possibly recalculate skb->hash.
* @skb: pointer to skb
* Return: hash
*/
BPF_FUNC_get_hash_recalc,
/**
* u64 bpf_get_current_task(void)
* Returns current task_struct
* Return: current
*/
BPF_FUNC_get_current_task,
/**
* bpf_probe_write_user(void *dst, void *src, int len)
* safely attempt to write to a location
* @dst: destination address in userspace
* @src: source address on stack
* @len: number of bytes to copy
* Return: 0 on success or negative error
*/
BPF_FUNC_probe_write_user,
__BPF_FUNC_MAX_ID, __BPF_FUNC_MAX_ID,
}; };
@ -347,9 +409,11 @@ enum bpf_func_id {
#define BPF_F_ZERO_CSUM_TX (1ULL << 1) #define BPF_F_ZERO_CSUM_TX (1ULL << 1)
#define BPF_F_DONT_FRAGMENT (1ULL << 2) #define BPF_F_DONT_FRAGMENT (1ULL << 2)
/* BPF_FUNC_perf_event_output flags. */ /* BPF_FUNC_perf_event_output and BPF_FUNC_perf_event_read flags. */
#define BPF_F_INDEX_MASK 0xffffffffULL #define BPF_F_INDEX_MASK 0xffffffffULL
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK #define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
/* BPF_FUNC_perf_event_output for sk_buff input context. */
#define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
/* user accessible mirror of in-kernel sk_buff. /* user accessible mirror of in-kernel sk_buff.
* new fields can only be added to the end of this structure * new fields can only be added to the end of this structure
@ -386,4 +450,24 @@ struct bpf_tunnel_key {
__u32 tunnel_label; __u32 tunnel_label;
}; };
/* User return codes for XDP prog type.
* A valid XDP program must return one of these defined values. All other
* return codes are reserved for future use. Unknown return codes will result
* in packet drop.
*/
enum xdp_action {
XDP_ABORTED = 0,
XDP_DROP,
XDP_PASS,
XDP_TX,
};
/* user accessible metadata for XDP packet hook
* new fields must be added to the end of this structure
*/
struct xdp_md {
__u32 data;
__u32 data_end;
};
#endif /* __LINUX_BPF_H__ */ #endif /* __LINUX_BPF_H__ */

View File

@ -57,6 +57,8 @@ enum devlink_command {
DEVLINK_CMD_SB_OCC_SNAPSHOT, DEVLINK_CMD_SB_OCC_SNAPSHOT,
DEVLINK_CMD_SB_OCC_MAX_CLEAR, DEVLINK_CMD_SB_OCC_MAX_CLEAR,
DEVLINK_CMD_ESWITCH_MODE_GET,
DEVLINK_CMD_ESWITCH_MODE_SET,
/* add new commands above here */ /* add new commands above here */
__DEVLINK_CMD_MAX, __DEVLINK_CMD_MAX,
@ -95,6 +97,11 @@ enum devlink_sb_threshold_type {
#define DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX 20 #define DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX 20
enum devlink_eswitch_mode {
DEVLINK_ESWITCH_MODE_LEGACY,
DEVLINK_ESWITCH_MODE_SWITCHDEV,
};
enum devlink_attr { enum devlink_attr {
/* don't change the order or add anything between, this is ABI! */ /* don't change the order or add anything between, this is ABI! */
DEVLINK_ATTR_UNSPEC, DEVLINK_ATTR_UNSPEC,
@ -125,6 +132,7 @@ enum devlink_attr {
DEVLINK_ATTR_SB_TC_INDEX, /* u16 */ DEVLINK_ATTR_SB_TC_INDEX, /* u16 */
DEVLINK_ATTR_SB_OCC_CUR, /* u32 */ DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
DEVLINK_ATTR_SB_OCC_MAX, /* u32 */ DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
/* add new attributes above here, update the policy in devlink.c */ /* add new attributes above here, update the policy in devlink.c */

View File

@ -50,6 +50,7 @@ enum {
FRA_FWMASK, /* mask for netfilter mark */ FRA_FWMASK, /* mask for netfilter mark */
FRA_OIFNAME, FRA_OIFNAME,
FRA_PAD, FRA_PAD,
FRA_L3MDEV, /* iif or oif is l3mdev goto its table */
__FRA_MAX __FRA_MAX
}; };

View File

@ -247,8 +247,37 @@ enum {
enum { enum {
BRIDGE_XSTATS_UNSPEC, BRIDGE_XSTATS_UNSPEC,
BRIDGE_XSTATS_VLAN, BRIDGE_XSTATS_VLAN,
BRIDGE_XSTATS_MCAST,
BRIDGE_XSTATS_PAD,
__BRIDGE_XSTATS_MAX __BRIDGE_XSTATS_MAX
}; };
#define BRIDGE_XSTATS_MAX (__BRIDGE_XSTATS_MAX - 1) #define BRIDGE_XSTATS_MAX (__BRIDGE_XSTATS_MAX - 1)
enum {
BR_MCAST_DIR_RX,
BR_MCAST_DIR_TX,
BR_MCAST_DIR_SIZE
};
/* IGMP/MLD statistics */
struct br_mcast_stats {
__u64 igmp_v1queries[BR_MCAST_DIR_SIZE];
__u64 igmp_v2queries[BR_MCAST_DIR_SIZE];
__u64 igmp_v3queries[BR_MCAST_DIR_SIZE];
__u64 igmp_leaves[BR_MCAST_DIR_SIZE];
__u64 igmp_v1reports[BR_MCAST_DIR_SIZE];
__u64 igmp_v2reports[BR_MCAST_DIR_SIZE];
__u64 igmp_v3reports[BR_MCAST_DIR_SIZE];
__u64 igmp_parse_errors;
__u64 mld_v1queries[BR_MCAST_DIR_SIZE];
__u64 mld_v2queries[BR_MCAST_DIR_SIZE];
__u64 mld_leaves[BR_MCAST_DIR_SIZE];
__u64 mld_v1reports[BR_MCAST_DIR_SIZE];
__u64 mld_v2reports[BR_MCAST_DIR_SIZE];
__u64 mld_parse_errors;
__u64 mcast_bytes[BR_MCAST_DIR_SIZE];
__u64 mcast_packets[BR_MCAST_DIR_SIZE];
};
#endif /* _LINUX_IF_BRIDGE_H */ #endif /* _LINUX_IF_BRIDGE_H */

View File

@ -87,6 +87,7 @@
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */ #define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ #define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
#define ETH_P_NCSI 0x88F8 /* NCSI protocol */
#define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */ #define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
#define ETH_P_TDLS 0x890D /* TDLS */ #define ETH_P_TDLS 0x890D /* TDLS */

View File

@ -156,6 +156,7 @@ enum {
IFLA_GSO_MAX_SEGS, IFLA_GSO_MAX_SEGS,
IFLA_GSO_MAX_SIZE, IFLA_GSO_MAX_SIZE,
IFLA_PAD, IFLA_PAD,
IFLA_XDP,
__IFLA_MAX __IFLA_MAX
}; };
@ -271,6 +272,7 @@ enum {
IFLA_BR_VLAN_DEFAULT_PVID, IFLA_BR_VLAN_DEFAULT_PVID,
IFLA_BR_PAD, IFLA_BR_PAD,
IFLA_BR_VLAN_STATS_ENABLED, IFLA_BR_VLAN_STATS_ENABLED,
IFLA_BR_MCAST_STATS_ENABLED,
__IFLA_BR_MAX, __IFLA_BR_MAX,
}; };
@ -820,6 +822,7 @@ enum {
IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */ IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
IFLA_STATS_LINK_64, IFLA_STATS_LINK_64,
IFLA_STATS_LINK_XSTATS, IFLA_STATS_LINK_XSTATS,
IFLA_STATS_LINK_XSTATS_SLAVE,
__IFLA_STATS_MAX, __IFLA_STATS_MAX,
}; };
@ -839,4 +842,15 @@ enum {
}; };
#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1) #define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
/* XDP section */
enum {
IFLA_XDP_UNSPEC,
IFLA_XDP_FD,
IFLA_XDP_ATTACHED,
__IFLA_XDP_MAX,
};
#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
#endif /* _LINUX_IF_LINK_H */ #endif /* _LINUX_IF_LINK_H */

View File

@ -26,6 +26,8 @@
#define MACSEC_MIN_ICV_LEN 8 #define MACSEC_MIN_ICV_LEN 8
#define MACSEC_MAX_ICV_LEN 32 #define MACSEC_MAX_ICV_LEN 32
/* upper limit for ICV length as recommended by IEEE802.1AE-2006 */
#define MACSEC_STD_ICV_LEN 16
enum macsec_attrs { enum macsec_attrs {
MACSEC_ATTR_UNSPEC, MACSEC_ATTR_UNSPEC,

View File

@ -113,6 +113,7 @@ enum {
IFLA_GRE_ENCAP_SPORT, IFLA_GRE_ENCAP_SPORT,
IFLA_GRE_ENCAP_DPORT, IFLA_GRE_ENCAP_DPORT,
IFLA_GRE_COLLECT_METADATA, IFLA_GRE_COLLECT_METADATA,
IFLA_GRE_IGNORE_DF,
__IFLA_GRE_MAX, __IFLA_GRE_MAX,
}; };

View File

@ -143,6 +143,7 @@ struct in6_flowlabel_req {
#define IPV6_TLV_PAD1 0 #define IPV6_TLV_PAD1 0
#define IPV6_TLV_PADN 1 #define IPV6_TLV_PADN 1
#define IPV6_TLV_ROUTERALERT 5 #define IPV6_TLV_ROUTERALERT 5
#define IPV6_TLV_CALIPSO 7 /* RFC 5570 */
#define IPV6_TLV_JUMBO 194 #define IPV6_TLV_JUMBO 194
#define IPV6_TLV_HAO 201 /* home address option */ #define IPV6_TLV_HAO 201 /* home address option */

View File

@ -72,6 +72,7 @@ enum {
INET_DIAG_BC_AUTO, INET_DIAG_BC_AUTO,
INET_DIAG_BC_S_COND, INET_DIAG_BC_S_COND,
INET_DIAG_BC_D_COND, INET_DIAG_BC_D_COND,
INET_DIAG_BC_DEV_COND, /* u32 ifindex */
}; };
struct inet_diag_hostcond { struct inet_diag_hostcond {

View File

@ -48,6 +48,7 @@ enum {
#define NDIAG_SHOW_MEMINFO 0x00000001 /* show memory info of a socket */ #define NDIAG_SHOW_MEMINFO 0x00000001 /* show memory info of a socket */
#define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */ #define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */
/* deprecated since 4.6 */
#define NDIAG_SHOW_RING_CFG 0x00000004 /* show ring configuration */ #define NDIAG_SHOW_RING_CFG 0x00000004 /* show ring configuration */
#endif #endif

View File

@ -61,8 +61,8 @@ struct tc_police {
__u32 mtu; __u32 mtu;
struct tc_ratespec rate; struct tc_ratespec rate;
struct tc_ratespec peakrate; struct tc_ratespec peakrate;
int refcnt; int refcnt;
int bindcnt; int bindcnt;
__u32 capab; __u32 capab;
}; };
@ -70,6 +70,7 @@ struct tcf_t {
__u64 install; __u64 install;
__u64 lastuse; __u64 lastuse;
__u64 expires; __u64 expires;
__u64 firstuse;
}; };
struct tc_cnt { struct tc_cnt {
@ -378,6 +379,18 @@ enum {
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1) #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
/* Match-all classifier */
enum {
TCA_MATCHALL_UNSPEC,
TCA_MATCHALL_CLASSID,
TCA_MATCHALL_ACT,
TCA_MATCHALL_FLAGS,
__TCA_MATCHALL_MAX,
};
#define TCA_MATCHALL_MAX (__TCA_MATCHALL_MAX - 1)
/* Extended Matches */ /* Extended Matches */
struct tcf_ematch_tree_hdr { struct tcf_ematch_tree_hdr {

View File

@ -27,6 +27,7 @@
#define SKBEDIT_F_PRIORITY 0x1 #define SKBEDIT_F_PRIORITY 0x1
#define SKBEDIT_F_QUEUE_MAPPING 0x2 #define SKBEDIT_F_QUEUE_MAPPING 0x2
#define SKBEDIT_F_MARK 0x4 #define SKBEDIT_F_MARK 0x4
#define SKBEDIT_F_PTYPE 0x8
struct tc_skbedit { struct tc_skbedit {
tc_gen; tc_gen;
@ -40,6 +41,7 @@ enum {
TCA_SKBEDIT_QUEUE_MAPPING, TCA_SKBEDIT_QUEUE_MAPPING,
TCA_SKBEDIT_MARK, TCA_SKBEDIT_MARK,
TCA_SKBEDIT_PAD, TCA_SKBEDIT_PAD,
TCA_SKBEDIT_PTYPE,
__TCA_SKBEDIT_MAX __TCA_SKBEDIT_MAX
}; };
#define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1) #define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)

View File

@ -115,12 +115,22 @@ enum {
#define TCP_CC_INFO 26 /* Get Congestion Control (optional) info */ #define TCP_CC_INFO 26 /* Get Congestion Control (optional) info */
#define TCP_SAVE_SYN 27 /* Record SYN headers for new connections */ #define TCP_SAVE_SYN 27 /* Record SYN headers for new connections */
#define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */ #define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */
#define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */
struct tcp_repair_opt { struct tcp_repair_opt {
__u32 opt_code; __u32 opt_code;
__u32 opt_val; __u32 opt_val;
}; };
struct tcp_repair_window {
__u32 snd_wl1;
__u32 snd_wnd;
__u32 max_window;
__u32 rcv_wnd;
__u32 rcv_wup;
};
enum { enum {
TCP_NO_QUEUE, TCP_NO_QUEUE,
TCP_RECV_QUEUE, TCP_RECV_QUEUE,

View File

@ -60,26 +60,48 @@ struct tipc_name_seq {
__u32 upper; __u32 upper;
}; };
/* TIPC Address Size, Offset, Mask specification for Z.C.N
*/
#define TIPC_NODE_BITS 12
#define TIPC_CLUSTER_BITS 12
#define TIPC_ZONE_BITS 8
#define TIPC_NODE_OFFSET 0
#define TIPC_CLUSTER_OFFSET TIPC_NODE_BITS
#define TIPC_ZONE_OFFSET (TIPC_CLUSTER_OFFSET + TIPC_CLUSTER_BITS)
#define TIPC_NODE_SIZE ((1UL << TIPC_NODE_BITS) - 1)
#define TIPC_CLUSTER_SIZE ((1UL << TIPC_CLUSTER_BITS) - 1)
#define TIPC_ZONE_SIZE ((1UL << TIPC_ZONE_BITS) - 1)
#define TIPC_NODE_MASK (TIPC_NODE_SIZE << TIPC_NODE_OFFSET)
#define TIPC_CLUSTER_MASK (TIPC_CLUSTER_SIZE << TIPC_CLUSTER_OFFSET)
#define TIPC_ZONE_MASK (TIPC_ZONE_SIZE << TIPC_ZONE_OFFSET)
#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK)
static __inline__ __u32 tipc_addr(unsigned int zone, static __inline__ __u32 tipc_addr(unsigned int zone,
unsigned int cluster, unsigned int cluster,
unsigned int node) unsigned int node)
{ {
return (zone << 24) | (cluster << 12) | node; return (zone << TIPC_ZONE_OFFSET) |
(cluster << TIPC_CLUSTER_OFFSET) |
node;
} }
static __inline__ unsigned int tipc_zone(__u32 addr) static __inline__ unsigned int tipc_zone(__u32 addr)
{ {
return addr >> 24; return addr >> TIPC_ZONE_OFFSET;
} }
static __inline__ unsigned int tipc_cluster(__u32 addr) static __inline__ unsigned int tipc_cluster(__u32 addr)
{ {
return (addr >> 12) & 0xfff; return (addr & TIPC_CLUSTER_MASK) >> TIPC_CLUSTER_OFFSET;
} }
static __inline__ unsigned int tipc_node(__u32 addr) static __inline__ unsigned int tipc_node(__u32 addr)
{ {
return addr & 0xfff; return addr & TIPC_NODE_MASK;
} }
/* /*

View File

@ -56,6 +56,9 @@ enum {
TIPC_NL_NET_GET, TIPC_NL_NET_GET,
TIPC_NL_NET_SET, TIPC_NL_NET_SET,
TIPC_NL_NAME_TABLE_GET, TIPC_NL_NAME_TABLE_GET,
TIPC_NL_MON_SET,
TIPC_NL_MON_GET,
TIPC_NL_MON_PEER_GET,
__TIPC_NL_CMD_MAX, __TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@ -72,6 +75,8 @@ enum {
TIPC_NLA_NODE, /* nest */ TIPC_NLA_NODE, /* nest */
TIPC_NLA_NET, /* nest */ TIPC_NLA_NET, /* nest */
TIPC_NLA_NAME_TABLE, /* nest */ TIPC_NLA_NAME_TABLE, /* nest */
TIPC_NLA_MON, /* nest */
TIPC_NLA_MON_PEER, /* nest */
__TIPC_NLA_MAX, __TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1 TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@ -166,6 +171,20 @@ enum {
TIPC_NLA_NAME_TABLE_MAX = __TIPC_NLA_NAME_TABLE_MAX - 1 TIPC_NLA_NAME_TABLE_MAX = __TIPC_NLA_NAME_TABLE_MAX - 1
}; };
/* Monitor info */
enum {
TIPC_NLA_MON_UNSPEC,
TIPC_NLA_MON_ACTIVATION_THRESHOLD, /* u32 */
TIPC_NLA_MON_REF, /* u32 */
TIPC_NLA_MON_ACTIVE, /* flag */
TIPC_NLA_MON_BEARER_NAME, /* string */
TIPC_NLA_MON_PEERCNT, /* u32 */
TIPC_NLA_MON_LISTGEN, /* u32 */
__TIPC_NLA_MON_MAX,
TIPC_NLA_MON_MAX = __TIPC_NLA_MON_MAX - 1
};
/* Publication info */ /* Publication info */
enum { enum {
TIPC_NLA_PUBL_UNSPEC, TIPC_NLA_PUBL_UNSPEC,
@ -182,6 +201,24 @@ enum {
TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1 TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1
}; };
/* Monitor peer info */
enum {
TIPC_NLA_MON_PEER_UNSPEC,
TIPC_NLA_MON_PEER_ADDR, /* u32 */
TIPC_NLA_MON_PEER_DOMGEN, /* u32 */
TIPC_NLA_MON_PEER_APPLIED, /* u32 */
TIPC_NLA_MON_PEER_UPMAP, /* u64 */
TIPC_NLA_MON_PEER_MEMBERS, /* tlv */
TIPC_NLA_MON_PEER_UP, /* flag */
TIPC_NLA_MON_PEER_HEAD, /* flag */
TIPC_NLA_MON_PEER_LOCAL, /* flag */
TIPC_NLA_MON_PEER_PAD, /* flag */
__TIPC_NLA_MON_PEER_MAX,
TIPC_NLA_MON_PEER_MAX = __TIPC_NLA_MON_PEER_MAX - 1
};
/* Nest, connection info */ /* Nest, connection info */
enum { enum {
TIPC_NLA_CON_UNSPEC, TIPC_NLA_CON_UNSPEC,

View File

@ -37,7 +37,7 @@ static void usage(void)
fprintf(stderr, " ip rule { flush | save | restore }\n"); fprintf(stderr, " ip rule { flush | save | restore }\n");
fprintf(stderr, " ip rule [ list ]\n"); fprintf(stderr, " ip rule [ list ]\n");
fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n"); fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n");
fprintf(stderr, " [ iif STRING ] [ oif STRING ] [ pref NUMBER ]\n"); fprintf(stderr, " [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]\n");
fprintf(stderr, "ACTION := [ table TABLE_ID ]\n"); fprintf(stderr, "ACTION := [ table TABLE_ID ]\n");
fprintf(stderr, " [ nat ADDRESS ]\n"); fprintf(stderr, " [ nat ADDRESS ]\n");
fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n"); fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n");
@ -57,6 +57,7 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
int host_len = -1; int host_len = -1;
__u32 table; __u32 table;
struct rtattr *tb[FRA_MAX+1]; struct rtattr *tb[FRA_MAX+1];
SPRINT_BUF(b1); SPRINT_BUF(b1);
if (n->nlmsg_type != RTM_NEWRULE && n->nlmsg_type != RTM_DELRULE) if (n->nlmsg_type != RTM_NEWRULE && n->nlmsg_type != RTM_DELRULE)
@ -74,7 +75,8 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, "Deleted "); fprintf(fp, "Deleted ");
if (tb[FRA_PRIORITY]) if (tb[FRA_PRIORITY])
fprintf(fp, "%u:\t", *(unsigned *)RTA_DATA(tb[FRA_PRIORITY])); fprintf(fp, "%u:\t",
rta_getattr_u32(tb[FRA_PRIORITY]));
else else
fprintf(fp, "0:\t"); fprintf(fp, "0:\t");
@ -84,11 +86,11 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (tb[FRA_SRC]) { if (tb[FRA_SRC]) {
if (r->rtm_src_len != host_len) { if (r->rtm_src_len != host_len) {
fprintf(fp, "from %s/%u ", fprintf(fp, "from %s/%u ",
rt_addr_n2a_rta(r->rtm_family, tb[FRA_SRC]), rt_addr_n2a_rta(r->rtm_family, tb[FRA_SRC]),
r->rtm_src_len); r->rtm_src_len);
} else { } else {
fprintf(fp, "from %s ", fprintf(fp, "from %s ",
format_host_rta(r->rtm_family, tb[FRA_SRC])); format_host_rta(r->rtm_family, tb[FRA_SRC]));
} }
} else if (r->rtm_src_len) { } else if (r->rtm_src_len) {
fprintf(fp, "from 0/%d ", r->rtm_src_len); fprintf(fp, "from 0/%d ", r->rtm_src_len);
@ -99,11 +101,11 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (tb[FRA_DST]) { if (tb[FRA_DST]) {
if (r->rtm_dst_len != host_len) { if (r->rtm_dst_len != host_len) {
fprintf(fp, "to %s/%u ", fprintf(fp, "to %s/%u ",
rt_addr_n2a_rta(r->rtm_family, tb[FRA_DST]), rt_addr_n2a_rta(r->rtm_family, tb[FRA_DST]),
r->rtm_dst_len); r->rtm_dst_len);
} else { } else {
fprintf(fp, "to %s ", fprintf(fp, "to %s ",
format_host_rta(r->rtm_family, tb[FRA_DST])); format_host_rta(r->rtm_family, tb[FRA_DST]));
} }
} else if (r->rtm_dst_len) { } else if (r->rtm_dst_len) {
fprintf(fp, "to 0/%d ", r->rtm_dst_len); fprintf(fp, "to 0/%d ", r->rtm_dst_len);
@ -111,7 +113,8 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (r->rtm_tos) { if (r->rtm_tos) {
SPRINT_BUF(b1); SPRINT_BUF(b1);
fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); fprintf(fp, "tos %s ",
rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
} }
if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) { if (tb[FRA_FWMARK] || tb[FRA_FWMASK]) {
@ -139,23 +142,29 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, "[detached] "); fprintf(fp, "[detached] ");
} }
if (tb[FRA_L3MDEV]) {
if (rta_getattr_u8(tb[FRA_L3MDEV]))
fprintf(fp, "lookup [l3mdev-table] ");
}
table = rtm_get_table(r, tb); table = rtm_get_table(r, tb);
if (table) { if (table) {
fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1))); fprintf(fp, "lookup %s ",
rtnl_rttable_n2a(table, b1, sizeof(b1)));
if (tb[FRA_SUPPRESS_PREFIXLEN]) { if (tb[FRA_SUPPRESS_PREFIXLEN]) {
int pl = rta_getattr_u32(tb[FRA_SUPPRESS_PREFIXLEN]); int pl = rta_getattr_u32(tb[FRA_SUPPRESS_PREFIXLEN]);
if (pl != -1) { if (pl != -1)
fprintf(fp, "suppress_prefixlength %d ", pl); fprintf(fp, "suppress_prefixlength %d ", pl);
}
} }
if (tb[FRA_SUPPRESS_IFGROUP]) { if (tb[FRA_SUPPRESS_IFGROUP]) {
int group = rta_getattr_u32(tb[FRA_SUPPRESS_IFGROUP]); int group = rta_getattr_u32(tb[FRA_SUPPRESS_IFGROUP]);
if (group != -1) { if (group != -1) {
SPRINT_BUF(b1); SPRINT_BUF(b1);
fprintf(fp, "suppress_ifgroup %s ", rtnl_group_n2a(group, b1, sizeof(b1))); fprintf(fp, "suppress_ifgroup %s ",
rtnl_group_n2a(group, b1, sizeof(b1)));
} }
} }
} }
@ -176,8 +185,8 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (r->rtm_type == RTN_NAT) { if (r->rtm_type == RTN_NAT) {
if (tb[RTA_GATEWAY]) { if (tb[RTA_GATEWAY]) {
fprintf(fp, "map-to %s ", fprintf(fp, "map-to %s ",
format_host_rta(r->rtm_family, format_host_rta(r->rtm_family,
tb[RTA_GATEWAY])); tb[RTA_GATEWAY]));
} else } else
fprintf(fp, "masquerade"); fprintf(fp, "masquerade");
} else if (r->rtm_type == FR_ACT_GOTO) { } else if (r->rtm_type == FR_ACT_GOTO) {
@ -191,7 +200,9 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
} else if (r->rtm_type == FR_ACT_NOP) } else if (r->rtm_type == FR_ACT_NOP)
fprintf(fp, "nop"); fprintf(fp, "nop");
else if (r->rtm_type != RTN_UNICAST) else if (r->rtm_type != RTN_UNICAST)
fprintf(fp, "%s", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1))); fprintf(fp, "%s",
rtnl_rtntype_n2a(r->rtm_type,
b1, sizeof(b1)));
fprintf(fp, "\n"); fprintf(fp, "\n");
fflush(fp); fflush(fp);
@ -218,7 +229,8 @@ static int save_rule_prep(void)
return 0; return 0;
} }
static int save_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) static int save_rule(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
{ {
int ret; int ret;
@ -276,7 +288,8 @@ static int rule_dump_check_magic(void)
ret = fread(&magic, sizeof(magic), 1, stdin); ret = fread(&magic, sizeof(magic), 1, stdin);
if (magic != rule_dump_magic) { if (magic != rule_dump_magic) {
fprintf(stderr, "Magic mismatch (%d elems, %x magic)\n", ret, magic); fprintf(stderr, "Magic mismatch (%d elems, %x magic)\n",
ret, magic);
return -1; return -1;
} }
@ -311,7 +324,9 @@ static int iprule_restore(void)
static int iprule_modify(int cmd, int argc, char **argv) static int iprule_modify(int cmd, int argc, char **argv)
{ {
int l3mdev_rule = 0;
int table_ok = 0; int table_ok = 0;
__u32 tid = 0;
struct { struct {
struct nlmsghdr n; struct nlmsghdr n;
struct rtmsg r; struct rtmsg r;
@ -340,14 +355,16 @@ static int iprule_modify(int cmd, int argc, char **argv)
NEXT_ARG(); NEXT_ARG();
get_prefix(&dst, *argv, req.r.rtm_family); get_prefix(&dst, *argv, req.r.rtm_family);
req.r.rtm_src_len = dst.bitlen; req.r.rtm_src_len = dst.bitlen;
addattr_l(&req.n, sizeof(req), FRA_SRC, &dst.data, dst.bytelen); addattr_l(&req.n, sizeof(req), FRA_SRC,
&dst.data, dst.bytelen);
} else if (strcmp(*argv, "to") == 0) { } else if (strcmp(*argv, "to") == 0) {
inet_prefix dst; inet_prefix dst;
NEXT_ARG(); NEXT_ARG();
get_prefix(&dst, *argv, req.r.rtm_family); get_prefix(&dst, *argv, req.r.rtm_family);
req.r.rtm_dst_len = dst.bitlen; req.r.rtm_dst_len = dst.bitlen;
addattr_l(&req.n, sizeof(req), FRA_DST, &dst.data, dst.bytelen); addattr_l(&req.n, sizeof(req), FRA_DST,
&dst.data, dst.bytelen);
} else if (matches(*argv, "preference") == 0 || } else if (matches(*argv, "preference") == 0 ||
matches(*argv, "order") == 0 || matches(*argv, "order") == 0 ||
matches(*argv, "priority") == 0) { matches(*argv, "priority") == 0) {
@ -370,15 +387,19 @@ static int iprule_modify(int cmd, int argc, char **argv)
__u32 fwmark, fwmask; __u32 fwmark, fwmask;
NEXT_ARG(); NEXT_ARG();
if ((slash = strchr(*argv, '/')) != NULL)
slash = strchr(*argv, '/');
if (slash != NULL)
*slash = '\0'; *slash = '\0';
if (get_u32(&fwmark, *argv, 0)) if (get_u32(&fwmark, *argv, 0))
invarg("fwmark value is invalid\n", *argv); invarg("fwmark value is invalid\n", *argv);
addattr32(&req.n, sizeof(req), FRA_FWMARK, fwmark); addattr32(&req.n, sizeof(req), FRA_FWMARK, fwmark);
if (slash) { if (slash) {
if (get_u32(&fwmask, slash+1, 0)) if (get_u32(&fwmask, slash+1, 0))
invarg("fwmask value is invalid\n", slash+1); invarg("fwmask value is invalid\n",
addattr32(&req.n, sizeof(req), FRA_FWMASK, fwmask); slash+1);
addattr32(&req.n, sizeof(req),
FRA_FWMASK, fwmask);
} }
} else if (matches(*argv, "realms") == 0) { } else if (matches(*argv, "realms") == 0) {
__u32 realm; __u32 realm;
@ -389,8 +410,6 @@ static int iprule_modify(int cmd, int argc, char **argv)
addattr32(&req.n, sizeof(req), FRA_FLOW, realm); addattr32(&req.n, sizeof(req), FRA_FLOW, realm);
} else if (matches(*argv, "table") == 0 || } else if (matches(*argv, "table") == 0 ||
strcmp(*argv, "lookup") == 0) { strcmp(*argv, "lookup") == 0) {
__u32 tid;
NEXT_ARG(); NEXT_ARG();
if (rtnl_rttable_a2n(&tid, *argv)) if (rtnl_rttable_a2n(&tid, *argv))
invarg("invalid table ID\n", *argv); invarg("invalid table ID\n", *argv);
@ -407,35 +426,46 @@ static int iprule_modify(int cmd, int argc, char **argv)
NEXT_ARG(); NEXT_ARG();
if (get_s32(&pl, *argv, 0) || pl < 0) if (get_s32(&pl, *argv, 0) || pl < 0)
invarg("suppress_prefixlength value is invalid\n", *argv); invarg("suppress_prefixlength value is invalid\n",
addattr32(&req.n, sizeof(req), FRA_SUPPRESS_PREFIXLEN, pl); *argv);
addattr32(&req.n, sizeof(req),
FRA_SUPPRESS_PREFIXLEN, pl);
} else if (matches(*argv, "suppress_ifgroup") == 0 || } else if (matches(*argv, "suppress_ifgroup") == 0 ||
strcmp(*argv, "sup_group") == 0) { strcmp(*argv, "sup_group") == 0) {
NEXT_ARG(); NEXT_ARG();
int group; int group;
if (rtnl_group_a2n(&group, *argv)) if (rtnl_group_a2n(&group, *argv))
invarg("Invalid \"suppress_ifgroup\" value\n", *argv); invarg("Invalid \"suppress_ifgroup\" value\n",
addattr32(&req.n, sizeof(req), FRA_SUPPRESS_IFGROUP, group); *argv);
addattr32(&req.n, sizeof(req),
FRA_SUPPRESS_IFGROUP, group);
} else if (strcmp(*argv, "dev") == 0 || } else if (strcmp(*argv, "dev") == 0 ||
strcmp(*argv, "iif") == 0) { strcmp(*argv, "iif") == 0) {
NEXT_ARG(); NEXT_ARG();
addattr_l(&req.n, sizeof(req), FRA_IFNAME, *argv, strlen(*argv)+1); addattr_l(&req.n, sizeof(req), FRA_IFNAME,
*argv, strlen(*argv)+1);
} else if (strcmp(*argv, "oif") == 0) { } else if (strcmp(*argv, "oif") == 0) {
NEXT_ARG(); NEXT_ARG();
addattr_l(&req.n, sizeof(req), FRA_OIFNAME, *argv, strlen(*argv)+1); addattr_l(&req.n, sizeof(req), FRA_OIFNAME,
*argv, strlen(*argv)+1);
} else if (strcmp(*argv, "l3mdev") == 0) {
addattr8(&req.n, sizeof(req), FRA_L3MDEV, 1);
table_ok = 1;
l3mdev_rule = 1;
} else if (strcmp(*argv, "nat") == 0 || } else if (strcmp(*argv, "nat") == 0 ||
matches(*argv, "map-to") == 0) { matches(*argv, "map-to") == 0) {
NEXT_ARG(); NEXT_ARG();
fprintf(stderr, "Warning: route NAT is deprecated\n"); fprintf(stderr, "Warning: route NAT is deprecated\n");
addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv)); addattr32(&req.n, sizeof(req), RTA_GATEWAY,
get_addr32(*argv));
req.r.rtm_type = RTN_NAT; req.r.rtm_type = RTN_NAT;
} else { } else {
int type; int type;
if (strcmp(*argv, "type") == 0) { if (strcmp(*argv, "type") == 0)
NEXT_ARG(); NEXT_ARG();
}
if (matches(*argv, "help") == 0) if (matches(*argv, "help") == 0)
usage(); usage();
else if (matches(*argv, "goto") == 0) { else if (matches(*argv, "goto") == 0) {
@ -445,7 +475,8 @@ static int iprule_modify(int cmd, int argc, char **argv)
NEXT_ARG(); NEXT_ARG();
if (get_u32(&target, *argv, 0)) if (get_u32(&target, *argv, 0))
invarg("invalid target\n", *argv); invarg("invalid target\n", *argv);
addattr32(&req.n, sizeof(req), FRA_GOTO, target); addattr32(&req.n, sizeof(req),
FRA_GOTO, target);
} else if (matches(*argv, "nop") == 0) } else if (matches(*argv, "nop") == 0)
type = FR_ACT_NOP; type = FR_ACT_NOP;
else if (rtnl_rtntype_a2n(&type, *argv)) else if (rtnl_rtntype_a2n(&type, *argv))
@ -457,6 +488,12 @@ static int iprule_modify(int cmd, int argc, char **argv)
argv++; argv++;
} }
if (l3mdev_rule && tid != 0) {
fprintf(stderr,
"table can not be specified for l3mdev rules\n");
return -EINVAL;
}
if (req.r.rtm_family == AF_UNSPEC) if (req.r.rtm_family == AF_UNSPEC)
req.r.rtm_family = AF_INET; req.r.rtm_family = AF_INET;
@ -470,7 +507,8 @@ static int iprule_modify(int cmd, int argc, char **argv)
} }
static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) static int flush_rule(const struct sockaddr_nl *who, struct nlmsghdr *n,
void *arg)
{ {
struct rtnl_handle rth2; struct rtnl_handle rth2;
struct rtmsg *r = NLMSG_DATA(n); struct rtmsg *r = NLMSG_DATA(n);
@ -545,7 +583,8 @@ int do_iprule(int argc, char **argv)
} else if (matches(argv[0], "help") == 0) } else if (matches(argv[0], "help") == 0)
usage(); usage();
fprintf(stderr, "Command \"%s\" is unknown, try \"ip rule help\".\n", *argv); fprintf(stderr,
"Command \"%s\" is unknown, try \"ip rule help\".\n", *argv);
exit(-1); exit(-1);
} }
@ -563,7 +602,8 @@ int do_multirule(int argc, char **argv)
case RTNL_FAMILY_IP6MR: case RTNL_FAMILY_IP6MR:
break; break;
default: default:
fprintf(stderr, "Multicast rules are only supported for IPv4/IPv6, was: %i\n", fprintf(stderr,
"Multicast rules are only supported for IPv4/IPv6, was: %i\n",
preferred_family); preferred_family);
exit(-1); exit(-1);
} }

View File

@ -56,7 +56,7 @@ in the delete command.
.PP .PP
.SS Configure a FOU receive port for GRE bound to 7777 .SS Configure a FOU receive port for GRE bound to 7777
.nf .nf
# ip fou add port 8888 ipproto 47 # ip fou add port 7777 ipproto 47
.PP .PP
.SS Configure a FOU receive port for IPIP bound to 8888 .SS Configure a FOU receive port for IPIP bound to 8888
.nf .nf

View File

@ -11,6 +11,8 @@ skbedit - SKB editing action
.IR PRIORITY " ] [" .IR PRIORITY " ] ["
.B mark .B mark
.IR MARK " ]" .IR MARK " ]"
.B ptype
.IR PTYPE " ]"
.SH DESCRIPTION .SH DESCRIPTION
The The
.B skbedit .B skbedit
@ -52,6 +54,13 @@ Change the packet's firewall mark value.
is an unsigned 32bit value in automatically detected format (i.e., prefix with is an unsigned 32bit value in automatically detected format (i.e., prefix with
.RB ' 0x ' .RB ' 0x '
for hexadecimal interpretation, etc.). for hexadecimal interpretation, etc.).
.TP
.BI ptype " PTYPE"
Override the packet's type. Useful for setting packet type to host when
needing to allow ingressing packets with the wrong MAC address but
correct IP address.
.I PTYPE
is one of: host, otherhost, broadcast, multicast
.SH SEE ALSO .SH SEE ALSO
.BR tc (8), .BR tc (8),
.BR tc-pedit (8) .BR tc-pedit (8)

View File

@ -26,14 +26,17 @@
#include "utils.h" #include "utils.h"
#include "tc_util.h" #include "tc_util.h"
#include <linux/tc_act/tc_skbedit.h> #include <linux/tc_act/tc_skbedit.h>
#include <linux/if_packet.h>
static void static void explain(void)
explain(void)
{ {
fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM]>\n" fprintf(stderr, "Usage: ... skbedit <[QM] [PM] [MM] [PT]>\n"
"QM = queue_mapping QUEUE_MAPPING\n" "QM = queue_mapping QUEUE_MAPPING\n"
"PM = priority PRIORITY\n" "PM = priority PRIORITY\n"
"MM = mark MARK\n" "MM = mark MARK\n"
"PT = ptype PACKETYPE\n"
"PACKETYPE = is one of:\n"
" host, otherhost, broadcast, multicast\n"
"QUEUE_MAPPING = device transmit queue to use\n" "QUEUE_MAPPING = device transmit queue to use\n"
"PRIORITY = classID to assign to priority field\n" "PRIORITY = classID to assign to priority field\n"
"MARK = firewall mark to set\n"); "MARK = firewall mark to set\n");
@ -55,7 +58,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
int ok = 0; int ok = 0;
struct rtattr *tail; struct rtattr *tail;
unsigned int tmp; unsigned int tmp;
__u16 queue_mapping; __u16 queue_mapping, ptype;
__u32 flags = 0, priority, mark; __u32 flags = 0, priority, mark;
struct tc_skbedit sel = { 0 }; struct tc_skbedit sel = { 0 };
@ -90,6 +93,24 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
return -1; return -1;
} }
ok++; ok++;
} else if (matches(*argv, "ptype") == 0) {
NEXT_ARG();
if (matches(*argv, "host") == 0) {
ptype = PACKET_HOST;
} else if (matches(*argv, "broadcast") == 0) {
ptype = PACKET_BROADCAST;
} else if (matches(*argv, "multicast") == 0) {
ptype = PACKET_MULTICAST;
} else if (matches(*argv, "otherhost") == 0) {
ptype = PACKET_OTHERHOST;
} else {
fprintf(stderr, "Illegal ptype (%s)\n",
*argv);
return -1;
}
flags |= SKBEDIT_F_PTYPE;
ok++;
} else if (matches(*argv, "help") == 0) { } else if (matches(*argv, "help") == 0) {
usage(); usage();
} else { } else {
@ -134,6 +155,9 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
if (flags & SKBEDIT_F_MARK) if (flags & SKBEDIT_F_MARK)
addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK, addattr_l(n, MAX_MSG, TCA_SKBEDIT_MARK,
&mark, sizeof(mark)); &mark, sizeof(mark));
if (flags & SKBEDIT_F_PTYPE)
addattr_l(n, MAX_MSG, TCA_SKBEDIT_PTYPE,
&ptype, sizeof(ptype));
tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail; tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail;
*argc_p = argc; *argc_p = argc;
@ -148,7 +172,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
SPRINT_BUF(b1); SPRINT_BUF(b1);
__u32 *priority; __u32 *priority;
__u32 *mark; __u32 *mark;
__u16 *queue_mapping; __u16 *queue_mapping, *ptype;
struct tc_skbedit *p = NULL; struct tc_skbedit *p = NULL;
if (arg == NULL) if (arg == NULL)
@ -176,8 +200,22 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg)
mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]); mark = RTA_DATA(tb[TCA_SKBEDIT_MARK]);
fprintf(f, " mark %d", *mark); fprintf(f, " mark %d", *mark);
} }
if (tb[TCA_SKBEDIT_PTYPE] != NULL) {
ptype = RTA_DATA(tb[TCA_SKBEDIT_PTYPE]);
if (*ptype == PACKET_HOST)
fprintf(f, " ptype host");
else if (*ptype == PACKET_BROADCAST)
fprintf(f, " ptype broadcast");
else if (*ptype == PACKET_MULTICAST)
fprintf(f, " ptype multicast");
else if (*ptype == PACKET_OTHERHOST)
fprintf(f, " ptype otherhost");
else
fprintf(f, " ptype %d", *ptype);
}
fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt); fprintf(f, "\n\t index %d ref %d bind %d",
p->index, p->refcnt, p->bindcnt);
if (show_stats) { if (show_stats) {
if (tb[TCA_SKBEDIT_TM]) { if (tb[TCA_SKBEDIT_TM]) {