FIP code has been added to the kernel and we want the
QoS layer in the kernel to filter FIP traffic into the
DCB negotiated traffic class. This patch addd an extra
'tc' call to fcoeplumb to filter the FIP packets.
This patch makes many of the filter functions generic
to work with multiple filters (one per ethertype) instead
of assuming that FCoE is the only desired filter.
This patch also fixes three defects-
1) incorrect argument parsing
delete_skbedit_filter()
{
ifname=$1
- queue=$?
+ queue=$2
$? doesn't make sense here
2) incorrect awk regex
The first check in the find_skbedit_filter() was searching for
/^filter.*parent.*protocol '$ethertype' ....
However, there are squared brackets around the ethertype. Since
the regex was searching for "protocol"<space><ethtype> it was
not matching "protocol"<space>[<ethertype>
This patch adds the brackets to the check.
3) When no qdisc was found the script would add a qdisc
and filter, but then immediately delete the newly added
qdisc. It would then re-add it and the filters again. This
was unnecessary, so I removed it.
It was explained to me that this was a workaround for a
'tc' defect, but with the latest version of iproute2
this workaround is not needed.
---
fcoeplumb.in | 104 +++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 66 insertions(+), 38 deletions(-)
diff --git a/fcoeplumb.in b/fcoeplumb.in
index a9ae9a8..edff338 100755
--- a/fcoeplumb.in
+++ b/fcoeplumb.in
@@ -32,10 +32,14 @@ usage()
#
QOS_DEF=3 # default user priority
FCOE_ETHERTYPE=35078 # Ethertype (0x8906): tc filter show is base 10
+FIP_ETHERTYPE=35092 # Ethertype (0x8914): tc filter show is base 10
FCOE_FILTER=0xfc0e # filter handle (must be lower-case hex)
+
+FCOE_FILTER_KEY=12345
+FIP_FILTER_KEY=67890
+
qdisc_id=1:
qos_list=
-FILTER_ID=
cmd=
# automake paths
pref...@prefix@
@@ -83,18 +87,10 @@ add_multiq_qdisc()
tc qdisc add dev $ifname root handle $qdisc_id multiq
}
-delete_qdisc()
-{
- ifname=$1
-
- [ "$DEBUG" = "yes" ] && $LOGGER \
- "tc qdisc del dev $ifname root"
- tc qdisc del dev $ifname root
-}
-
get_filter_id()
{
ifname=$1
+ filter_key=$2
retry_count=0
while true
@@ -105,13 +101,15 @@ get_filter_id()
retry_count=$(($retry_count-1))
done
- FILTER_ID=`echo "$ifname 12345" | \
- awk '{ printf("0x%x%06x", substr($1,4), $2) }'`
+ echo "`echo "$ifname $filter_key" | \
+ awk '{ printf("0x%x%06x", substr($1,4), $2) }'`"
}
find_skbedit_filter()
{
ifname=$1
+ ethertype=$2
+ filter_id=$3
found=`tc filter show dev $ifname | awk '
BEGIN {
@@ -120,11 +118,11 @@ find_skbedit_filter()
x3 = 0
queue = 8
}
- /^filter.*parent.*protocol '$FCOE_ETHERTYPE'.* handle '$FILTER_ID'/ {
+ /^filter.*parent.*protocol \['$ethertype'\].* handle '$filter_id'/ {
if (x1 == 0 && x2 == 0 && x3 == 0)
x1 = 1
}
- /cmp.*u16 at 12 layer 1 mask 0xffff eq '$FCOE_ETHERTYPE'.*\)/ {
+ /cmp.*u16 at 12 layer 1 mask 0xffff eq '$ethertype'.*\)/ {
if (x1 == 1 && x2 == 0 && x3 == 0)
x2 = 1
}
@@ -144,22 +142,24 @@ find_skbedit_filter()
delete_skbedit_filter()
{
ifname=$1
- queue=$?
+ queue=$2
+ ethertype=$3
+ filter_id=$4
[ "$DEBUG" = "yes" ] && $LOGGER \
"tc filter delete dev $ifname skbedit queue_mapping $queue"
PARENT=`tc filter show dev $ifname | awk \
- '/^filter.*parent.*protocol '$FCOE_ETHERTYPE'.* handle
'$FILTER_ID'/ \
+ '/^filter.*parent.*protocol \['$ethertype'\].* handle
'$filter_id'/ \
{ print $3 }'`
PRIO=`tc filter show dev $ifname | awk \
- '/^filter.*parent.*protocol '$FCOE_ETHERTYPE'.* handle
'$FILTER_ID'/ \
+ '/^filter.*parent.*protocol \['$ethertype'\].* handle
'$filter_id'/ \
{ print $7 }'`
tc filter delete dev $ifname parent $PARENT \
- protocol $FCOE_ETHERTYPE pref $PRIO handle $FILTER_ID basic
match \
- 'cmp(u16' at 12 layer 1 mask 0xffff eq $FCOE_ETHERTYPE')' \
+ protocol $ethertype pref $PRIO handle $filter_id basic match \
+ 'cmp(u16' at 12 layer 1 mask 0xffff eq $ethertype')' \
action skbedit queue_mapping $queue
tc filter delete dev $ifname parent $PARENT \
- protocol $FCOE_ETHERTYPE pref $PRIO basic
+ protocol $ethertype pref $PRIO basic
}
add_skbedit_filter()
@@ -167,12 +167,14 @@ add_skbedit_filter()
ifname=$1
qdisc_id=$2
queue=$3
+ ethertype=$4
+ filter_id=$5
[ "$DEBUG" = "yes" ] && $LOGGER \
"tc filter add dev $ifname skbedit queue_mapping $queue"
- tc filter add dev $ifname parent $qdisc_id protocol $FCOE_ETHERTYPE \
- handle $FILTER_ID basic match 'cmp(u16' at 12 \
- layer 1 mask 0xffff eq $FCOE_ETHERTYPE')' \
+ tc filter add dev $ifname parent $qdisc_id protocol $ethertype \
+ handle $filter_id basic match 'cmp(u16' at 12 \
+ layer 1 mask 0xffff eq $ethertype')' \
action skbedit queue_mapping $queue
}
@@ -180,18 +182,20 @@ replace_skbedit_filter()
{
ifname=$1
queue=$2
+ ethertype=$3
+ filter_id=$4
[ "$DEBUG" = "yes" ] && $LOGGER \
"tc filter replace dev $ifname skbedit queue_mapping $queue"
PARENT=`tc filter show dev $ifname | awk \
- '/^filter.*parent.*protocol '$FCOE_ETHERTYPE'.* handle
'$FILTER_ID'/ \
+ '/^filter.*parent.*protocol \['$ethertype'\].* handle
'$filter_id'/ \
{ print $3 }'`
PRIO=`tc filter show dev $ifname | \
- awk '/^filter.*parent.*protocol '$FCOE_ETHERTYPE'.* handle
'$FILTER_ID'/ \
+ awk '/^filter.*parent.*protocol \['$ethertype'\].* handle
'$filter_id'/ \
{ print $7 }'`
tc filter replace dev $ifname parent $PARENT protocol \
- $FCOE_ETHERTYPE pref $PRIO handle $FILTER_ID basic match \
- 'cmp(u16' at 12 layer 1 mask 0xffff eq $FCOE_ETHERTYPE')' \
+ $ethertype pref $PRIO handle $filter_id basic match \
+ 'cmp(u16' at 12 layer 1 mask 0xffff eq $ethertype')' \
action skbedit queue_mapping $queue
}
@@ -261,15 +265,23 @@ do
done
# This must be the first to do after parsing the command arguments!
-# Notice that the FILTER_ID is used in find_skbedit_filter(),
+# Notice that the filter ID is used in find_skbedit_filter(),
# add_skbedit_filter(), replace_skbedit_filter().
-get_filter_id $ifname
+fcoe_filter_id=`get_filter_id $ifname $FCOE_FILTER_KEY`
+fip_filter_id=`get_filter_id $ifname $FIP_FILTER_KEY`
if [ "$cmd" == "disable" ]; then
remove_fcoe_interface $ifname
- find_skbedit_filter $ifname
+ # Remove the FCoE filters
+ find_skbedit_filter $ifname $FCOE_ETHERTYPE $fcoe_filter_id
found_filter=$?
- [ $found_filter -le 7 ] && delete_skbedit_filter $ifname $found_filter
+ [ $found_filter -le 7 ] && delete_skbedit_filter $ifname $found_filter
$FCOE_ETHERTYPE $fcoe_filter_id
+
+ # Remove the FIP filters
+ find_skbedit_filter $ifname $FIP_ETHERTYPE $fip_filter_id
+ found_filter=$?
+ [ $found_filter -le 7 ] && delete_skbedit_filter $ifname $found_filter
$FIP_ETHERTYPE $fip_filter_id
+
else
#
# Choose the best QOS to use for FCoE out of the listed choices.
@@ -317,25 +329,41 @@ else
found_qdisc=$?
if [ $found_qdisc -eq 1 ]; then
+ # Adjust the FCoE filter
[ "$DEBUG" = "yes" ] && $LOGGER "$ifname: Qdisc is found"
- find_skbedit_filter $ifname
+ find_skbedit_filter $ifname $FCOE_ETHERTYPE $fcoe_filter_id
found_filter=$?
if [ $found_filter -gt 7 ]; then
- add_skbedit_filter $ifname $qdisc_id $qos_queue
+ add_skbedit_filter $ifname $qdisc_id $qos_queue \
+ $FCOE_ETHERTYPE $fcoe_filter_id
elif [ $found_filter -ne $qos_queue ]; then
[ "$DEBUG" = "yes" ] && $LOGGER \
"$ifname: Filter is found and QOS is different"
- replace_skbedit_filter $ifname $qos_queue
+ replace_skbedit_filter $ifname $qos_queue
$FCOE_ETHERTYPE $fcoe_filter_id
+ else
+ [ "$DEBUG" = "yes" ] && $LOGGER \
+ "$ifname: Filter is found and is identical"
+ fi
+
+ # Adjust the FIP filter
+ [ "$DEBUG" = "yes" ] && $LOGGER "$ifname: Qdisc is found"
+ find_skbedit_filter $ifname $FIP_ETHERTYPE $fip_filter_id
+ found_filter=$?
+ if [ $found_filter -gt 7 ]; then
+ add_skbedit_filter $ifname $qdisc_id $qos_queue \
+ $FIP_ETHERTYPE $fip_filter_id
+ elif [ $found_filter -ne $qos_queue ]; then
+ [ "$DEBUG" = "yes" ] && $LOGGER \
+ "$ifname: Filter is found and QOS is different"
+ replace_skbedit_filter $ifname $qos_queue
$FIP_ETHERTYPE $fip_filter_id
else
[ "$DEBUG" = "yes" ] && $LOGGER \
"$ifname: Filter is found and is identical"
fi
else
add_multiq_qdisc $ifname $qdisc_id
- add_skbedit_filter $ifname $qdisc_id $qos_queue
- delete_qdisc $ifname
- add_multiq_qdisc $ifname $qdisc_id
- add_skbedit_filter $ifname $qdisc_id $qos_queue
+ add_skbedit_filter $ifname $qdisc_id $qos_queue $FCOE_ETHERTYPE
$fcoe_filter_id
+ add_skbedit_filter $ifname $qdisc_id $qos_queue $FIP_ETHERTYPE
$fip_filter_id
fi
if [ "$cmd" = "enable" ]; then
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel