summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2016-10-03 13:05:48 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2016-10-07 21:32:24 +0000
commit3ee44040c66cbe47ff292ac7fb0badccbe2afe6d (patch)
treea52a4dd0750467845f237ee5e4e88aa95ea11bab /test
parent4a7e58bf481adb843707eec4a81213776a6d5212 (diff)
unicast RPF for FIB2.0
In a heirarchical FIB performing a unicast RPF check would require the traversal of the data-plane graph to seek out all the adjacency objects and then read those to find their interface. This is not efficient. Instead, for each path-list we construct a list of unique input interfaces and link this uRPF-list against the entry in the prefix table. In the data-plane the uRPF list can be retrieved from the load-balance lookup result and the RPF check is a simple and efficient walk across the minimal interface list. The uRPF-list is maintained as the routing heirarchy changes, in a similar way to the data-plane object graph. We also provide a knob to allow an arbitrary prefix to pass the loose check. Change-Id: Ie7c0ae3c4483ef467cfd5b136ee0315ff98ec15b Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'test')
0 files changed, 0 insertions, 0 deletions
scheme: dark) { .highlight .hll { background-color: #49483e } .highlight .c { color: #75715e } /* Comment */ .highlight .err { color: #960050; background-color: #1e0010 } /* Error */ .highlight .k { color: #66d9ef } /* Keyword */ .highlight .l { color: #ae81ff } /* Literal */ .highlight .n { color: #f8f8f2 } /* Name */ .highlight .o { color: #f92672 } /* Operator */ .highlight .p { color: #f8f8f2 } /* Punctuation */ .highlight .ch { color: #75715e } /* Comment.Hashbang */ .highlight .cm { color: #75715e } /* Comment.Multiline */ .highlight .cp { color: #75715e } /* Comment.Preproc */ .highlight .cpf { color: #75715e } /* Comment.PreprocFile */ .highlight .c1 { color: #75715e } /* Comment.Single */ .highlight .cs { color: #75715e } /* Comment.Special */ .highlight .gd { color: #f92672 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gi { color: #a6e22e } /* Generic.Inserted */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #75715e } /* Generic.Subheading */ .highlight .kc { color: #66d9ef } /* Keyword.Constant */ .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ .highlight .kn { color: #f92672 } /* Keyword.Namespace */ .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ .highlight .kt { color: #66d9ef } /* Keyword.Type */ .highlight .ld { color: #e6db74 } /* Literal.Date */ .highlight .m { color: #ae81ff } /* Literal.Number */ .highlight .s { color: #e6db74 } /* Literal.String */ .highlight .na { color: #a6e22e } /* Name.Attribute */ .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ .highlight .nc { color: #a6e22e } /* Name.Class */ .highlight .no { color: #66d9ef } /* Name.Constant */ .highlight .nd { color: #a6e22e } /* Name.Decorator */ .highlight .ni { color: #f8f8f2 } /* Name.Entity */ .highlight .ne { color: #a6e22e } /* Name.Exception */ .highlight .nf { color: #a6e22e } /* Name.Function */ .highlight .nl { color: #f8f8f2 } /* Name.Label */ .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ .highlight .nx { color: #a6e22e } /* Name.Other */ .highlight .py { color: #f8f8f2 } /* Name.Property */ .highlight .nt { color: #f92672 } /* Name.Tag */ .highlight .nv { color: #f8f8f2 } /* Name.Variable */ .highlight .ow { color: #f92672 } /* Operator.Word */ .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ .highlight .sc { color: #e6db74 } /* Literal.String.Char */ .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ .highlight .se { color: #ae81ff } /* Literal.String.Escape */ .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ .highlight .sx { color: #e6db74 } /* Literal.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
#!/bin/bash

function die() {
	echo "ERROR: $*" >&2
	exit 1
}
function pci-unbind() {
	echo $1 | sudo tee /sys/bus/pci/devices/$1/driver/unbind > /dev/null
}
function pci-bind() {
	pci-unbind $1
	echo $2 | sudo tee /sys/bus/pci/devices/$1/driver_override > /dev/null
	echo $1 | sudo tee /sys/bus/pci/drivers/$2/bind > /dev/null
	echo | sudo tee /sys/bus/pci/devices/$1/driver_override > /dev/null
}

function show_vfs() {
	path=$1
	netdev=$2
	printf "\nVirtual Functions:\n%-2s %-12s %-9s %-12s %-17s %s\n" \
	  "ID" "PCI Addr" "PCI ID" "Driver" "MAC Addr" "Config"
	for vf_path in ${path}/virtfn*; do
		vf=$(basename $(readlink ${vf_path}))
		vfid=$(basename ${vf_path//virtfn/})
		line=$(ip link show dev ${netdev} | grep "vf ${vfid}")
		driver=$(basename $(readlink ${vf_path}/driver))
		pciid="$(cat ${vf_path}/vendor | cut -dx -f2):$(cat ${vf_path}/device | cut -dx -f2)"
		mac=$(echo $line | sed -n -E -e 's/.*MAC ([0-9a-f:]+),.*/\1/p')
		cfg=$(echo $line | cut -d, -f2-)

		printf "%-2s %-12s %-9s %-12s %-17s%s\n" \
		  $vfid $vf $pciid $driver $mac "$cfg"
	done
}
function get_pci_addr() {
	local addr
	if [ -d /sys/class/net/$2/device ]; then
		addr=$(basename $(readlink /sys/class/net/${2}/device))
	else
		addr=$2
	fi
	if [ ! -d /sys/bus/pci/devices/${pci_addr} ]; then
		die "PCI device $2 doesn't exist"
	fi
	eval "$1=${addr}"
}

function show () {
	get_pci_addr pci_addr $1
	path="/sys/bus/pci/devices/${pci_addr}"

	if [ ! -f ${path}/sriov_numvfs ]; then
		die "PCI device $1 is not SR-IOV device"
	fi

	printf "%-20s: %s\n" "PCI Address" ${pci_addr}
	printf "%-20s: %s\n" "PCI ID" \
		"$(cat ${path}/vendor | cut -dx -f2):$(cat ${path}/device | cut -dx -f2)"
	printf "%-20s: %s\n" "Driver name" $(basename $(readlink ${path}/driver))
	printf "%-20s: %s\n" "Driver Version" $(cat ${path}/driver/module/version)
	printf "%-20s: %s\n" "PCI Link Speed (max)" "$(cat ${path}/current_link_speed) ($(cat ${path}/max_link_speed))"
	printf "%-20s: %s\n" "PCI Link Width (max)" "$(cat ${path}/current_link_width) ($(cat ${path}/max_link_width))"
	printf "%-20s: %s\n" "NUMA Node" $(cat ${path}/numa_node)
	printf "%-20s: %s\n" "Number of VFs" $(cat ${path}/sriov_numvfs)
	printf "%-20s: %s\n" "Total VFs" $(cat ${path}/sriov_totalvfs)
	if [ -d ${path}/net/* ] ; then
		netdev=$(basename ${path}/net/*)
		netdev_path=${path}/net/${netdev}
		printf "%-20s: %s\n" "Interface" ${netdev}
		printf "%-20s: %s\n" "MAC Address" $(cat ${netdev_path}/address)
		printf "%-20s: %s\n" "Speed" $(cat ${netdev_path}/speed)
		printf "%-20s: %s\n" "State" $(cat ${netdev_path}/operstate)
	fi

	[ $(cat ${path}/sriov_numvfs) -gt 0 ] && show_vfs ${path} ${netdev}
}

function remove_all () {
	get_pci_addr pci_addr $1
	path="/sys/bus/pci/devices/${pci_addr}"
	[ $(cat ${path}/sriov_numvfs) -gt 0 ] || die "No VFs configured on $1"
	echo 0 | sudo tee ${path}/sriov_numvfs > /dev/null
	echo "VFs removed..."
}

function create () {
	get_pci_addr pci_addr $1
	path="/sys/bus/pci/devices/${pci_addr}"
	[ $(cat ${path}/sriov_numvfs) -gt 0 ] && die "VFs already configured on $1"
	[ "0$2" -gt 0 ] || die "Please specify number of VFs to create"
	echo $2 | sudo tee ${path}/sriov_numvfs > /dev/null
	[ -d ${path}/net/* ] || die "No net device for $1"
	netdev=$(basename ${path}/net/*)
	netdev_path=${path}/net/${netdev}

	mac_prefix=$(cat ${netdev_path}/address | cut -d: -f1,3,4,5,6 )
	for vf_path in ${path}/virtfn*; do
		vf=$(basename $(readlink ${vf_path}))
		vfid=$(basename ${vf_path//virtfn/})
		mac="${mac_prefix}:$(printf "%02x" ${vfid})"
		sudo ip link set dev ${netdev} vf ${vfid} mac ${mac}
		sudo ip link set dev ${netdev} vf ${vfid} trust on
		sudo ip link set dev ${netdev} vf ${vfid} spoofchk off
		pci-bind ${vf} vfio-pci
	done

	[ $(cat ${path}/sriov_numvfs) -gt 0 ] && show_vfs ${path} ${netdev}
}

function help() {

cat << __EOF__

$0 show <dev>
  Displays information about <dev> where <dev> is PCI address
  or linux interface name.

$0 remove-all <dev>
  Remove all virtual functions from device <dev>.

$0 create <dev> <num>
  Create <num> virtual functions on device<dev>.
__EOF__
}

case $1 in
	show)
		show $2
		;;
	create)
		create $2 $3
		;;
	remove-all)
		remove_all $2
		;;
	help)
		help $2
		;;
	*)
		echo "Please specify command (show, create, remove-all)"
		help
		;;
esac