cxgbetool(8): Provide user interface for hashfilters, hardware NAT, and
other filtering related features that were recently added to the driver. Sponsored by: Chelsio Communications
This commit is contained in:
parent
b3daa684d8
commit
36ea2fe3bf
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2015, Chelsio Inc
|
||||
.\" Copyright (c) 2015, 2018 Chelsio Inc
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -31,7 +31,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 13, 2018
|
||||
.Dd May 14, 2018
|
||||
.Dt CXGBETOOL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -48,9 +48,19 @@
|
||||
.It
|
||||
.Nm Ar nexus Cm context Bro Cm ingress | egress | fl | cong Brc Ar cntxt_id
|
||||
.It
|
||||
.Nm Ar nexus Cm filter mode Op Ar match-criteria ...
|
||||
.Nm Ar nexus Cm hashfilter mode
|
||||
.It
|
||||
.Nm Ar nexus Cm filter Ar idx Bro Ar filter-specification | Cm delete Brc
|
||||
.Nm Ar nexus Cm hashfilter Ar filter-specification
|
||||
.It
|
||||
.Nm Ar nexus Cm hashfilter Ar idx Cm delete
|
||||
.It
|
||||
.Nm Ar nexus Cm hashfilter list
|
||||
.It
|
||||
.Nm Ar nexus Cm filter mode
|
||||
.It
|
||||
.Nm Ar nexus Cm filter Ar idx Ar filter-specification
|
||||
.It
|
||||
.Nm Ar nexus Cm filter Ar idx Cm delete
|
||||
.It
|
||||
.Nm Ar nexus Cm filter list
|
||||
.It
|
||||
@ -141,44 +151,51 @@ context id of a freelist manager.
|
||||
The FLM context id is displayed in the
|
||||
egress context dump of a freelist as FLMcontextID.
|
||||
.El
|
||||
.It Cm filter mode Op Ar match-criteria ...
|
||||
Display or set the nexus's filter mode.
|
||||
.Ar match-criteria
|
||||
is a whitespace separated list of criteria from the table below.
|
||||
Each criteria has an associated budget which is also listed in the table.
|
||||
The total budget allowed is 36 and attempts to set a filter mode that
|
||||
exceeds this will be rejected.
|
||||
Every filter must conform to the filter mode -- multiple match criteria
|
||||
per filter are allowed but only from among those in the current setting
|
||||
of the filter mode.
|
||||
The filter mode can only be changed when there are no existing filters.
|
||||
Its default value is
|
||||
.Cm ipv4 ipv6 sip dip sport dport matchtype proto vlan iport fcoe
|
||||
.Pp
|
||||
.Bl -item -compact
|
||||
.It
|
||||
.Cm hashfilter mode
|
||||
.It
|
||||
.Cm filter mode
|
||||
.El
|
||||
Display a list of match-criteria available for use in filter rules.
|
||||
A full list of match-criteria known to the chip is in the table below but not
|
||||
all can be used together and the firmware sets up the available parameters based
|
||||
on "filterMode" in the configuration file.
|
||||
Every filter must conform to the filter mode -- multiple match criteria per
|
||||
filter are allowed but only from among those in the current setting of the
|
||||
filter mode.
|
||||
The filter mode for hash filters is a subset of that for normal TCAM filters and
|
||||
depends on the "filterMask" setting in the firmware configuration file.
|
||||
Hash filters do not support masked matches and an exact value for every
|
||||
parameter in the output of "hashfilter mode" (except ipv4/ipv6) must be provided
|
||||
when creating a hash filter.
|
||||
.Pp
|
||||
(Note that
|
||||
.Ar mask
|
||||
defaults to all 1s when not provided explicitly.
|
||||
Hash filters do not support masked matches.
|
||||
Also note that many of the items being matched are discrete numeric
|
||||
values rather than bit fields and should be masked with caution.)
|
||||
.TS
|
||||
center expand;
|
||||
cb cb cb cbw(40m)
|
||||
cb c l l.
|
||||
Criteria Budget Usage Matches if ...
|
||||
cb cb cbw(40m)
|
||||
cb l l.
|
||||
Criteria Usage Matches if ...
|
||||
_
|
||||
ipv4 0 T{
|
||||
ipv4 T{
|
||||
.Cm type ipv4
|
||||
T} T{
|
||||
incoming packet is an IPv4 datagram.
|
||||
T}
|
||||
_
|
||||
ipv6 0 T{
|
||||
ipv6 T{
|
||||
.Cm type ipv6
|
||||
T} T{
|
||||
incoming packet is an IPv6 datagram.
|
||||
T}
|
||||
_
|
||||
sip 0 T{
|
||||
sip T{
|
||||
.Cm sip Ar addr Ns Op / Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the source address in an incoming IP datagram with
|
||||
@ -189,7 +206,7 @@ equals
|
||||
can be an IPv4 or IPv6 address.
|
||||
T}
|
||||
_
|
||||
dip 0 T{
|
||||
dip T{
|
||||
.Cm dip Ar addr Ns Op / Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the destination address in an incoming IP datagram with
|
||||
@ -200,7 +217,7 @@ equals
|
||||
can be an IPv4 or IPv6 address.
|
||||
T}
|
||||
_
|
||||
sport 0 T{
|
||||
sport T{
|
||||
.Cm sport Ar port Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the source port in an incoming TCP or UDP datagram with
|
||||
@ -209,7 +226,7 @@ equals
|
||||
.Ar port Ns .
|
||||
T}
|
||||
_
|
||||
dport 0 T{
|
||||
dport T{
|
||||
.Cm dport Ar port Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the destination port in an incoming TCP or UDP datagram with
|
||||
@ -218,13 +235,13 @@ equals
|
||||
.Ar port Ns .
|
||||
T}
|
||||
_
|
||||
fcoe 1 T{
|
||||
fcoe T{
|
||||
.Cm fcoe Brq 0 | 1
|
||||
T} T{
|
||||
incoming frame is Fibre Channel over Ethernet(1) or not(0).
|
||||
T}
|
||||
_
|
||||
iport 3 T{
|
||||
iport T{
|
||||
.Cm iport Ar val Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the ingress port with
|
||||
@ -239,7 +256,7 @@ Note that ingress port is not a bit field so it is not always possible
|
||||
to match an arbitrary subset of ingress ports with a single filter rule.
|
||||
T}
|
||||
_
|
||||
ovlan 17 T{
|
||||
ovlan T{
|
||||
.Cm ovlan Ar tag Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the 16-bit outer VLAN tag of an incoming frame with
|
||||
@ -248,7 +265,7 @@ equals
|
||||
.Ar tag Ns .
|
||||
T}
|
||||
_
|
||||
vlan 17 T{
|
||||
vlan T{
|
||||
.Cm vlan Ar tag Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the 16-bit VLAN tag of an incoming QinQ frame with
|
||||
@ -258,7 +275,7 @@ equals
|
||||
The inner VLAN tag is used if the incoming frame is QinQ.
|
||||
T}
|
||||
_
|
||||
tos 8 T{
|
||||
tos T{
|
||||
.Cm tos Ar val Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the 8-bit IP Type of Service/IPv6 Traffic Class in an
|
||||
@ -268,7 +285,7 @@ equals
|
||||
.Ar val Ns .
|
||||
T}
|
||||
_
|
||||
proto 8 T{
|
||||
proto T{
|
||||
.Cm proto Ar ipproto Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the 8-bit IP protocol in an incoming packet with
|
||||
@ -277,7 +294,7 @@ equals
|
||||
.Ar ipproto Ns .
|
||||
T}
|
||||
_
|
||||
ethtype 16 T{
|
||||
ethtype T{
|
||||
.Cm ethtype Ar type Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the 16-bit Ethernet type field of an incoming frame with
|
||||
@ -286,7 +303,7 @@ equals
|
||||
.Ar type Ns .
|
||||
T}
|
||||
_
|
||||
macidx 9 T{
|
||||
macidx T{
|
||||
.Cm macidx Ar idx Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the MAC Address Match Index of an incoming frame with
|
||||
@ -299,7 +316,7 @@ MPS hash. See
|
||||
for more information.
|
||||
T}
|
||||
_
|
||||
matchtype 3 T{
|
||||
matchtype T{
|
||||
.Cm matchtype Ar type Ns Op : Ns Ar mask
|
||||
T} T{
|
||||
bitwise and of the Match Type of an incoming frame with
|
||||
@ -345,19 +362,138 @@ Not documented. Do not use.
|
||||
.El
|
||||
T}
|
||||
_
|
||||
frag 1 T{
|
||||
frag T{
|
||||
.Cm frag Brq 0 | 1
|
||||
T} T{
|
||||
incoming frame is part of a fragmented IP datagram(1) or not(0).
|
||||
T}
|
||||
.TE
|
||||
.It Cm filter Ar idx Ar filter-specification
|
||||
Program a filter at the index specified by
|
||||
.Ar idx Ns .
|
||||
.Pp
|
||||
.Bl -item -compact
|
||||
.It
|
||||
.Cm hashfilter Ar filter-specification
|
||||
.It
|
||||
.Cm filter Ar idx Ar filter-specification
|
||||
.El
|
||||
Program a filter.
|
||||
.Pp
|
||||
TCAM filters: The number of available filters is in
|
||||
dev.<nexus>.<instance>.nfilters.
|
||||
.Ar idx
|
||||
must be an unused index between 0 and nfilters - 1.
|
||||
IPv6 filters consume 4 consecutive entries on T4/T5 and and 2 on T6 and
|
||||
.Ar idx
|
||||
must be aligned to 4 or 2 in this case.
|
||||
.Pp
|
||||
Hash filters: These reside in the card's memory instead of its TCAM and are
|
||||
enabled with a special configuration file that is selected with
|
||||
.Cm hw.cxgbe.config_file="hashfilter"
|
||||
in loader.conf.
|
||||
There are at least half a million filters available with the sample config
|
||||
shipped with the driver.
|
||||
Note that the hardware selects the index for a hashfilter and this index is
|
||||
displayed when the filter is created.
|
||||
Hash and TCAM filters can be used together.
|
||||
.Pp
|
||||
.Ar filter-specification
|
||||
consists of one or more matches to try against an incoming frame and an
|
||||
action to perform when all matches succeed.
|
||||
.It Cm filter Ar idx Cm delete
|
||||
consists of one or more matches (see Usage in the table above) to try against an
|
||||
incoming frame, an action to perform when all matches succeed, and some
|
||||
additional operational parameters.
|
||||
Hashfilters require an exact value for the 5-tuple (sip, dip, sport, dport,
|
||||
proto) and for any other match-criteria listed in "hashfilter mode".
|
||||
Possible filter actions are
|
||||
.Cm drop Ns ,
|
||||
.Cm pass Ns , or
|
||||
.Cm switch Ns .
|
||||
.Pp
|
||||
.Bl -tag -width nat_dport -offset indent -compact
|
||||
Operational parameters that can be used with all filters:
|
||||
.It Cm hitcnts
|
||||
Count filter hits: 0 or 1 (default).
|
||||
.It Cm prio
|
||||
Filter has priority over active and server regions of TCAM: 0 (default) or 1.
|
||||
.El
|
||||
.Pp
|
||||
.Bl -tag -width nat_dport -offset indent -compact
|
||||
Operational parameters that can be used with filters with
|
||||
.Cm action pass Ns :
|
||||
.It Cm queue
|
||||
Rx queue index to which to deliver the packet. By default, packets that hit a
|
||||
filter with action pass are delivered based on their RSS hash as usual. Use
|
||||
this to steer them to a particular queue.
|
||||
.It Cm rpttid
|
||||
Report the filter tid instead of the RSS hash in the rx descriptor.
|
||||
0 (default) or 1.
|
||||
.It Cm tcbhash
|
||||
Select TCB hash information in rx descriptor.
|
||||
0 (default) or 1
|
||||
.El
|
||||
.Pp
|
||||
.Bl -tag -width nat_dport -offset indent -compact
|
||||
Operational parameters that can be used with filters with
|
||||
.Cm action switch Ns :
|
||||
.It Cm eport
|
||||
Egress port number on which to send the packet matching the filter.
|
||||
0 to dev.<nexus>.<instance>.nports - 1.
|
||||
.It Cm dmac
|
||||
Replace packet destination MAC address with the one provided before switching
|
||||
it out of eport.
|
||||
.It Cm smac
|
||||
Replace packet source MAC address with the one provided before switching it
|
||||
out of eport.
|
||||
.It Cm swapmac
|
||||
Swap packet source and destination MAC addresses before switching it out of
|
||||
eport.
|
||||
.It Cm vlan
|
||||
Insert, remove, or rewrite the VLAN tag before switching the packet out of
|
||||
eport.
|
||||
.Cm vlan=none
|
||||
removes the tag,
|
||||
.Cm vlan= Ns Ar tag
|
||||
replaces the existing tag with the one provided, and
|
||||
.Cm vlan=+ Ns Ar tag
|
||||
inserts the given tag into the frame.
|
||||
.It Cm nat
|
||||
Specify the desired NAT mode. Valid NAT modes values are:
|
||||
.Bl -tag -width dip-dp-sip -compact
|
||||
.It Cm dip
|
||||
Perform NAT on destination IP.
|
||||
.It Cm dip-dp
|
||||
Perform NAT on destination IP, destination port.
|
||||
.It Cm dip-dp-sip
|
||||
Perform NAT on destination IP, destination port, source IP.
|
||||
.It Cm dip-dp-sp
|
||||
Perform NAT on destination IP, destination port, source port.
|
||||
.It Cm sip-sp
|
||||
Perform NAT on source IP, source port.
|
||||
.It Cm dip-sip-sp
|
||||
Perform NAT on destination IP, source IP, source port.
|
||||
.It Cm all
|
||||
Perform NAT on all 4-tuple fields.
|
||||
.El
|
||||
.It Cm natflag
|
||||
Perform NAT only on segments which do not have TCP FIN or RST set.
|
||||
.It Cm natseq
|
||||
Perform NAT only if incoming segment's sequence number + payload length is less
|
||||
than this supplied value.
|
||||
.It Cm nat_dip
|
||||
Perform NAT using this destination IP.
|
||||
.It Cm nat_sip
|
||||
Perform NAT using this source IP.
|
||||
.It Cm nat_dport
|
||||
Perform NAT using this destination port.
|
||||
.It Cm nat_sport
|
||||
Perform NAT using this source port.
|
||||
Perform NAT only if incoming segment's sequence number + payload length is less
|
||||
than this supplied value.
|
||||
.El
|
||||
.Pp
|
||||
.Bl -item -compact
|
||||
.It
|
||||
.Cm hashfilter Ar idx Cm delete
|
||||
.It
|
||||
.Cm filter Ar idx Cm delete
|
||||
.El
|
||||
Delete filter that is at the given index.
|
||||
.It Cm filter Cm list
|
||||
List all filters programmed into the hardware.
|
||||
|
@ -97,6 +97,10 @@ usage(FILE *fp)
|
||||
"\tfilter <idx> delete|clear delete a filter\n"
|
||||
"\tfilter list list all filters\n"
|
||||
"\tfilter mode [<match>] ... get/set global filter mode\n"
|
||||
"\thashfilter [<param> <val>] ... set a hashfilter\n"
|
||||
"\thashfilter <idx> delete|clear delete a hashfilter\n"
|
||||
"\thashfilter list list all hashfilters\n"
|
||||
"\thashfilter mode get global hashfilter mode\n"
|
||||
"\ti2c <port> <devaddr> <addr> [<len>] read from i2c device\n"
|
||||
"\tloadboot <bi.bin> [pf|offset <val>] install boot image\n"
|
||||
"\tloadboot clear [pf|offset <val>] remove boot image\n"
|
||||
@ -600,7 +604,7 @@ do_show_info_header(uint32_t mode)
|
||||
*/
|
||||
static int
|
||||
parse_val_mask(const char *param, const char *args[], uint32_t *val,
|
||||
uint32_t *mask)
|
||||
uint32_t *mask, int hashfilter)
|
||||
{
|
||||
char *p;
|
||||
|
||||
@ -615,9 +619,18 @@ parse_val_mask(const char *param, const char *args[], uint32_t *val,
|
||||
}
|
||||
|
||||
if (p[0] == ':' && p[1] != 0) {
|
||||
if (hashfilter) {
|
||||
warnx("param %s: mask not allowed for "
|
||||
"hashfilter or nat params", param);
|
||||
return (EINVAL);
|
||||
}
|
||||
*mask = strtoul(p+1, &p, 0);
|
||||
if (p[0] == 0)
|
||||
return (0);
|
||||
} else {
|
||||
warnx("param %s: mask not allowed for hashfilter",
|
||||
param);
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,7 +664,7 @@ parse_val_mask(const char *param, const char *args[], uint32_t *val,
|
||||
*/
|
||||
static int
|
||||
parse_ipaddr(const char *param, const char *args[], int *afp, uint8_t addr[],
|
||||
uint8_t mask[])
|
||||
uint8_t mask[], int maskless)
|
||||
{
|
||||
const char *colon, *afn;
|
||||
char *slash;
|
||||
@ -708,6 +721,11 @@ parse_ipaddr(const char *param, const char *args[], int *afp, uint8_t addr[],
|
||||
char *p;
|
||||
unsigned int prefix = strtoul(slash + 1, &p, 10);
|
||||
|
||||
if (maskless) {
|
||||
warnx("mask cannot be provided for maskless specification");
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (p == slash + 1) {
|
||||
warnx("missing address prefix for %s", param);
|
||||
return (EINVAL);
|
||||
@ -725,13 +743,15 @@ parse_ipaddr(const char *param, const char *args[], int *afp, uint8_t addr[],
|
||||
masksize = prefix;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in mask.
|
||||
*/
|
||||
for (m = mask; masksize >= 8; m++, masksize -= 8)
|
||||
*m = ~0;
|
||||
if (masksize)
|
||||
*m = ~0 << (8 - masksize);
|
||||
if (mask != NULL) {
|
||||
/*
|
||||
* Fill in mask.
|
||||
*/
|
||||
for (m = mask; masksize >= 8; m++, masksize -= 8)
|
||||
*m = ~0;
|
||||
if (masksize)
|
||||
*m = ~0 << (8 - masksize);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -917,7 +937,7 @@ do_show_one_filter_info(struct t4_filter *t, uint32_t mode)
|
||||
}
|
||||
|
||||
static int
|
||||
show_filters(void)
|
||||
show_filters(int hash)
|
||||
{
|
||||
uint32_t mode = 0, header = 0;
|
||||
struct t4_filter t;
|
||||
@ -929,6 +949,7 @@ show_filters(void)
|
||||
return (rc);
|
||||
|
||||
t.idx = 0;
|
||||
t.fs.hash = hash;
|
||||
for (t.idx = 0; ; t.idx++) {
|
||||
rc = doit(CHELSIO_T4_GET_FILTER, &t);
|
||||
if (rc != 0 || t.idx == 0xffffffff)
|
||||
@ -945,9 +966,9 @@ show_filters(void)
|
||||
}
|
||||
|
||||
static int
|
||||
get_filter_mode(void)
|
||||
get_filter_mode(int hashfilter)
|
||||
{
|
||||
uint32_t mode = 0;
|
||||
uint32_t mode = hashfilter;
|
||||
int rc;
|
||||
|
||||
rc = doit(CHELSIO_T4_GET_FILTER_MODE, &mode);
|
||||
@ -1066,19 +1087,20 @@ set_filter_mode(int argc, const char *argv[])
|
||||
}
|
||||
|
||||
static int
|
||||
del_filter(uint32_t idx)
|
||||
del_filter(uint32_t idx, int hashfilter)
|
||||
{
|
||||
struct t4_filter t;
|
||||
|
||||
t.fs.hash = hashfilter;
|
||||
t.idx = idx;
|
||||
|
||||
return doit(CHELSIO_T4_DEL_FILTER, &t);
|
||||
}
|
||||
|
||||
static int
|
||||
set_filter(uint32_t idx, int argc, const char *argv[])
|
||||
set_filter(uint32_t idx, int argc, const char *argv[], int hash)
|
||||
{
|
||||
int af = AF_UNSPEC, start_arg = 0;
|
||||
int rc, af = AF_UNSPEC, start_arg = 0;
|
||||
struct t4_filter t;
|
||||
|
||||
if (argc < 2) {
|
||||
@ -1088,6 +1110,7 @@ set_filter(uint32_t idx, int argc, const char *argv[])
|
||||
bzero(&t, sizeof (t));
|
||||
t.idx = idx;
|
||||
t.fs.hitcnts = 1;
|
||||
t.fs.hash = hash;
|
||||
|
||||
for (start_arg = 0; start_arg + 2 <= argc; start_arg += 2) {
|
||||
const char **args = &argv[start_arg];
|
||||
@ -1111,66 +1134,74 @@ set_filter(uint32_t idx, int argc, const char *argv[])
|
||||
return (EINVAL);
|
||||
}
|
||||
af = newaf;
|
||||
} else if (!parse_val_mask("fcoe", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("fcoe", args, &val, &mask, hash)) {
|
||||
t.fs.val.fcoe = val;
|
||||
t.fs.mask.fcoe = mask;
|
||||
} else if (!parse_val_mask("iport", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("iport", args, &val, &mask, hash)) {
|
||||
t.fs.val.iport = val;
|
||||
t.fs.mask.iport = mask;
|
||||
} else if (!parse_val_mask("ovlan", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("ovlan", args, &val, &mask, hash)) {
|
||||
t.fs.val.vnic = val;
|
||||
t.fs.mask.vnic = mask;
|
||||
t.fs.val.ovlan_vld = 1;
|
||||
t.fs.mask.ovlan_vld = 1;
|
||||
} else if (!parse_val_mask("ivlan", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("ivlan", args, &val, &mask, hash)) {
|
||||
t.fs.val.vlan = val;
|
||||
t.fs.mask.vlan = mask;
|
||||
t.fs.val.vlan_vld = 1;
|
||||
t.fs.mask.vlan_vld = 1;
|
||||
} else if (!parse_val_mask("pf", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("pf", args, &val, &mask, hash)) {
|
||||
t.fs.val.vnic &= 0x1fff;
|
||||
t.fs.val.vnic |= (val & 0x7) << 13;
|
||||
t.fs.mask.vnic &= 0x1fff;
|
||||
t.fs.mask.vnic |= (mask & 0x7) << 13;
|
||||
t.fs.val.pfvf_vld = 1;
|
||||
t.fs.mask.pfvf_vld = 1;
|
||||
} else if (!parse_val_mask("vf", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("vf", args, &val, &mask, hash)) {
|
||||
t.fs.val.vnic &= 0xe000;
|
||||
t.fs.val.vnic |= val & 0x1fff;
|
||||
t.fs.mask.vnic &= 0xe000;
|
||||
t.fs.mask.vnic |= mask & 0x1fff;
|
||||
t.fs.val.pfvf_vld = 1;
|
||||
t.fs.mask.pfvf_vld = 1;
|
||||
} else if (!parse_val_mask("tos", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("tos", args, &val, &mask, hash)) {
|
||||
t.fs.val.tos = val;
|
||||
t.fs.mask.tos = mask;
|
||||
} else if (!parse_val_mask("proto", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("proto", args, &val, &mask, hash)) {
|
||||
t.fs.val.proto = val;
|
||||
t.fs.mask.proto = mask;
|
||||
} else if (!parse_val_mask("ethtype", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("ethtype", args, &val, &mask, hash)) {
|
||||
t.fs.val.ethtype = val;
|
||||
t.fs.mask.ethtype = mask;
|
||||
} else if (!parse_val_mask("macidx", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("macidx", args, &val, &mask, hash)) {
|
||||
t.fs.val.macidx = val;
|
||||
t.fs.mask.macidx = mask;
|
||||
} else if (!parse_val_mask("matchtype", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("matchtype", args, &val, &mask, hash)) {
|
||||
t.fs.val.matchtype = val;
|
||||
t.fs.mask.matchtype = mask;
|
||||
} else if (!parse_val_mask("frag", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("frag", args, &val, &mask, hash)) {
|
||||
t.fs.val.frag = val;
|
||||
t.fs.mask.frag = mask;
|
||||
} else if (!parse_val_mask("dport", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("dport", args, &val, &mask, hash)) {
|
||||
t.fs.val.dport = val;
|
||||
t.fs.mask.dport = mask;
|
||||
} else if (!parse_val_mask("sport", args, &val, &mask)) {
|
||||
} else if (!parse_val_mask("sport", args, &val, &mask, hash)) {
|
||||
t.fs.val.sport = val;
|
||||
t.fs.mask.sport = mask;
|
||||
} else if (!parse_ipaddr("dip", args, &af, t.fs.val.dip,
|
||||
t.fs.mask.dip)) {
|
||||
t.fs.mask.dip, hash)) {
|
||||
/* nada */;
|
||||
} else if (!parse_ipaddr("sip", args, &af, t.fs.val.sip,
|
||||
t.fs.mask.sip)) {
|
||||
t.fs.mask.sip, hash)) {
|
||||
/* nada */;
|
||||
} else if (!parse_ipaddr("nat_dip", args, &af, t.fs.nat_dip, NULL, 1)) {
|
||||
/*nada*/;
|
||||
} else if (!parse_ipaddr("nat_sip", args, &af, t.fs.nat_sip, NULL, 1)) {
|
||||
/*nada*/
|
||||
} else if (!parse_val_mask("nat_dport", args, &val, &mask, 1)) {
|
||||
t.fs.nat_dport = val;
|
||||
} else if (!parse_val_mask("nat_sport", args, &val, &mask, 1)) {
|
||||
t.fs.nat_sport = val;
|
||||
} else if (!strcmp(argv[start_arg], "action")) {
|
||||
if (!strcmp(argv[start_arg + 1], "pass"))
|
||||
t.fs.action = FILTER_PASS;
|
||||
@ -1198,6 +1229,33 @@ set_filter(uint32_t idx, int argc, const char *argv[])
|
||||
t.fs.dirsteerhash = 1;
|
||||
} else if (!parse_val("eport", args, &val)) {
|
||||
t.fs.eport = val;
|
||||
} else if (!parse_val("swapmac", args, &val)) {
|
||||
t.fs.swapmac = 1;
|
||||
} else if (!strcmp(argv[start_arg], "nat")) {
|
||||
if (!strcmp(argv[start_arg + 1], "dip"))
|
||||
t.fs.nat_mode = NAT_MODE_DIP;
|
||||
else if (!strcmp(argv[start_arg + 1], "dip-dp"))
|
||||
t.fs.nat_mode = NAT_MODE_DIP_DP;
|
||||
else if (!strcmp(argv[start_arg + 1], "dip-dp-sip"))
|
||||
t.fs.nat_mode = NAT_MODE_DIP_DP_SIP;
|
||||
else if (!strcmp(argv[start_arg + 1], "dip-dp-sp"))
|
||||
t.fs.nat_mode = NAT_MODE_DIP_DP_SP;
|
||||
else if (!strcmp(argv[start_arg + 1], "sip-sp"))
|
||||
t.fs.nat_mode = NAT_MODE_SIP_SP;
|
||||
else if (!strcmp(argv[start_arg + 1], "dip-sip-sp"))
|
||||
t.fs.nat_mode = NAT_MODE_DIP_SIP_SP;
|
||||
else if (!strcmp(argv[start_arg + 1], "all"))
|
||||
t.fs.nat_mode = NAT_MODE_ALL;
|
||||
else {
|
||||
warnx("unknown nat type \"%s\"; known types are dip, "
|
||||
"dip-dp, dip-dp-sip, dip-dp-sp, sip-sp, "
|
||||
"dip-sip-sp, and all", argv[start_arg + 1]);
|
||||
return (EINVAL);
|
||||
}
|
||||
} else if (!parse_val("natseq", args, &val)) {
|
||||
t.fs.nat_seq_chk = val;
|
||||
} else if (!parse_val("natflag", args, &val)) {
|
||||
t.fs.nat_flag_chk = 1;
|
||||
} else if (!strcmp(argv[start_arg], "dmac")) {
|
||||
struct ether_addr *daddr;
|
||||
|
||||
@ -1229,7 +1287,7 @@ set_filter(uint32_t idx, int argc, const char *argv[])
|
||||
} else if (argv[start_arg + 1][0] == '+') {
|
||||
t.fs.newvlan = VLAN_INSERT;
|
||||
} else if (isdigit(argv[start_arg + 1][0]) &&
|
||||
!parse_val_mask("vlan", args, &val, &mask)) {
|
||||
!parse_val_mask("vlan", args, &val, &mask, hash)) {
|
||||
t.fs.val.vlan = val;
|
||||
t.fs.mask.vlan = mask;
|
||||
t.fs.val.vlan_vld = 1;
|
||||
@ -1265,11 +1323,17 @@ set_filter(uint32_t idx, int argc, const char *argv[])
|
||||
* Check basic sanity of option combinations.
|
||||
*/
|
||||
if (t.fs.action != FILTER_SWITCH &&
|
||||
(t.fs.eport || t.fs.newdmac || t.fs.newsmac || t.fs.newvlan)) {
|
||||
warnx("prio, port dmac, smac and vlan only make sense with"
|
||||
(t.fs.eport || t.fs.newdmac || t.fs.newsmac || t.fs.newvlan ||
|
||||
t.fs.swapmac || t.fs.nat_mode)) {
|
||||
warnx("port, dmac, smac, vlan, and nat only make sense with"
|
||||
" \"action switch\"");
|
||||
return (EINVAL);
|
||||
}
|
||||
if (!t.fs.nat_mode && (t.fs.nat_seq_chk || t.fs.nat_flag_chk ||
|
||||
*t.fs.nat_dip || *t.fs.nat_sip || t.fs.nat_dport || t.fs.nat_sport)) {
|
||||
warnx("nat params only make sense with valid nat mode");
|
||||
return (EINVAL);
|
||||
}
|
||||
if (t.fs.action != FILTER_PASS &&
|
||||
(t.fs.rpttid || t.fs.dirsteer || t.fs.maskhash)) {
|
||||
warnx("rpttid, queue and tcbhash don't make sense with"
|
||||
@ -1282,18 +1346,21 @@ set_filter(uint32_t idx, int argc, const char *argv[])
|
||||
}
|
||||
|
||||
t.fs.type = (af == AF_INET6 ? 1 : 0); /* default IPv4 */
|
||||
return doit(CHELSIO_T4_SET_FILTER, &t);
|
||||
rc = doit(CHELSIO_T4_SET_FILTER, &t);
|
||||
if (hash && rc == 0)
|
||||
printf("%d\n", t.idx);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static int
|
||||
filter_cmd(int argc, const char *argv[])
|
||||
filter_cmd(int argc, const char *argv[], int hashfilter)
|
||||
{
|
||||
long long val;
|
||||
uint32_t idx;
|
||||
char *s;
|
||||
|
||||
if (argc == 0) {
|
||||
warnx("filter: no arguments.");
|
||||
warnx("%sfilter: no arguments.", hashfilter ? "hash" : "");
|
||||
return (EINVAL);
|
||||
};
|
||||
|
||||
@ -1302,20 +1369,29 @@ filter_cmd(int argc, const char *argv[])
|
||||
if (argc != 1)
|
||||
warnx("trailing arguments after \"list\" ignored.");
|
||||
|
||||
return show_filters();
|
||||
return show_filters(hashfilter);
|
||||
}
|
||||
|
||||
/* mode */
|
||||
if (argc == 1 && strcmp(argv[0], "mode") == 0)
|
||||
return get_filter_mode();
|
||||
return get_filter_mode(hashfilter);
|
||||
|
||||
/* mode <mode> */
|
||||
if (strcmp(argv[0], "mode") == 0)
|
||||
if (!hashfilter && strcmp(argv[0], "mode") == 0)
|
||||
return set_filter_mode(argc - 1, argv + 1);
|
||||
|
||||
/* <idx> ... */
|
||||
s = str_to_number(argv[0], NULL, &val);
|
||||
if (*s || val > 0xffffffffU) {
|
||||
if (*s || val < 0 || val > 0xffffffffU) {
|
||||
if (hashfilter) {
|
||||
/*
|
||||
* No numeric index means this must be a request to
|
||||
* create a new hashfilter and we are already at the
|
||||
* paramter/value list.
|
||||
*/
|
||||
idx = (uint32_t) -1;
|
||||
goto setf;
|
||||
}
|
||||
warnx("\"%s\" is neither an index nor a filter subcommand.",
|
||||
argv[0]);
|
||||
return (EINVAL);
|
||||
@ -1325,11 +1401,16 @@ filter_cmd(int argc, const char *argv[])
|
||||
/* <idx> delete|clear */
|
||||
if (argc == 2 &&
|
||||
(strcmp(argv[1], "delete") == 0 || strcmp(argv[1], "clear") == 0)) {
|
||||
return del_filter(idx);
|
||||
return del_filter(idx, hashfilter);
|
||||
}
|
||||
|
||||
/* <idx> [<param> <val>] ... */
|
||||
return set_filter(idx, argc - 1, argv + 1);
|
||||
/* skip <idx> */
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
setf:
|
||||
/* [<param> <val>] ... */
|
||||
return set_filter(idx, argc, argv, hashfilter);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3356,7 +3437,7 @@ run_cmd(int argc, const char *argv[])
|
||||
else if (!strcmp(cmd, "regdump"))
|
||||
rc = dump_regs(argc, argv);
|
||||
else if (!strcmp(cmd, "filter"))
|
||||
rc = filter_cmd(argc, argv);
|
||||
rc = filter_cmd(argc, argv, 0);
|
||||
else if (!strcmp(cmd, "context"))
|
||||
rc = get_sge_context(argc, argv);
|
||||
else if (!strcmp(cmd, "loadfw"))
|
||||
@ -3387,6 +3468,8 @@ run_cmd(int argc, const char *argv[])
|
||||
rc = dumpstate(argc, argv);
|
||||
else if (!strcmp(cmd, "policy"))
|
||||
rc = load_offload_policy(argc, argv);
|
||||
else if (!strcmp(cmd, "hashfilter"))
|
||||
rc = filter_cmd(argc, argv, 1);
|
||||
else {
|
||||
rc = EINVAL;
|
||||
warnx("invalid command \"%s\"", cmd);
|
||||
|
Loading…
Reference in New Issue
Block a user