diff --git a/build_debian.sh b/build_debian.sh index 1010fbc26e0f..8c69a922bfe7 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -200,7 +200,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install \ ## Note: don't install python-apt by pip, older than Debian repo one sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ file \ - ifupdown \ + ifupdown2 \ iproute2 \ bridge-utils \ isc-dhcp-client \ @@ -232,6 +232,7 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in unzip \ gdisk \ sysfsutils \ + squashfs-tools \ grub2-common \ rsyslog \ ethtool \ @@ -340,6 +341,8 @@ set /files/etc/sysctl.conf/net.ipv6.conf.eth0.keep_addr_on_down 1 set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0 +set /files/etc/sysctl.conf/net.ipv4.tcp_l3mdev_accept 1 + set /files/etc/sysctl.conf/net.core.rmem_max 2097152 set /files/etc/sysctl.conf/net.core.wmem_max 2097152 " -r $FILESYSTEM_ROOT @@ -368,6 +371,7 @@ sudo cp files/dhcp/rfc3442-classless-routes $FILESYSTEM_ROOT/etc/dhcp/dhclient-e sudo cp files/dhcp/sethostname $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/dhclient.conf $FILESYSTEM_ROOT/etc/dhcp/ ## Version file diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index ed8df864cd06..c2ca592a64c0 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -260,12 +260,6 @@ sudo dpkg --root=$FILESYSTEM_ROOT -P {{ debname }} sudo rm -f $FILESYSTEM_ROOT/usr/sbin/policy-rc.d -## Revise /etc/init.d/networking and /lib/systemd/system/networking.service for Arista switches -if [ "$image_type" = "aboot" ]; then - sudo sed -i 's/udevadm settle/udevadm settle -E \/sys\/class\/net\/eth0/' $FILESYSTEM_ROOT/etc/init.d/networking - sudo sed -i 's/udevadm settle/udevadm settle -E \/sys\/class\/net\/eth0/' $FILESYSTEM_ROOT/lib/systemd/system/networking.service -fi - ## copy platform rc.local sudo cp $IMAGE_CONFIGS/platform/rc.local $FILESYSTEM_ROOT/etc/ diff --git a/files/dhcp/vrf b/files/dhcp/vrf new file mode 100644 index 000000000000..b64a57c2b2cd --- /dev/null +++ b/files/dhcp/vrf @@ -0,0 +1,234 @@ +# +# DHCLIENT exit hook for vrf support. +# +# Code ported from https://github.com/CumulusNetworks/vrf under GPLv2 license +# (see https://github.com/CumulusNetworks/vrf/blob/master/debian/copyright). +# + +# Get table_id for device enslaved to a vrf. +vrf_get_table_dev() +{ + local table_id + + # If vrf_slave is not in the output, device is not enslaved. + table_id=$(ip -o -d link show dev ${1} 2>/dev/null |\ + egrep ' vrf_slave table [0-9]*' |\ + sed -e 's/.*vrf_slave table \([0-9]*\) .*/\1/') + + [ -z "${table_id}" ] && return 1 + + echo ${table_id} + + return 0 +} + +# Get table_id for vrf device. +vrf_get_table() +{ + local table_id + + table_id=$(ip -o -d link show dev ${1} 2>/dev/null |\ + egrep ' vrf table [0-9]*' |\ + sed -e 's/.*vrf table \([0-9]*\) .*/\1/') + + [ -z "${table_id}" ] && return 1 + + echo ${table_id} + + return 0 +} + +vrf_exists() +{ + local vrf=${1} + local n + + [ "$vrf" = "default" ] && return 0 + + # ip link show dev type vrf happily returns 0 even though + # is not of type vrf. Hence the wc -l. + n=$(ip -br link show dev ${vrf} type vrf 2>/dev/null | wc -l) + [ ${n} -eq 1 ] && return 0 + + return $? +} + +# Check vrf device contains only alphanumeric characters. +get_vrf_arg() +{ + local vrf + + vrf=$(echo $1 | tr -cd [:alnum:]) + if [ "$vrf" != "$1" ]; then + echo "Invalid VRF" >&2 + return 1 + fi + + echo $vrf +} + +vrf_table() +{ + local table_id + local vrf + + vrf=$(get_vrf_arg ${1}) + [ $? -ne 0 ] && return 1 + + vrf_exists $vrf + if [ $? -eq 0 ]; then + vrf_get_table $vrf + return 0 + fi + + # Maybe this is a device, not a vrf. + table_id=$(vrf_get_table_dev $vrf) + if [ $? -eq 0 ]; then + echo ${table_id} + return 0 + fi + + return 1 +} + +table_id=$(vrf_table ${interface}) + +if [ -n "${table_id}" ]; then + +case "$reason" in + BOUND|RENEW|REBIND|REBOOT) + if [ -z "$old_ip_address" ] || + [ "$old_ip_address" != "$new_ip_address" ] || + [ "$reason" = "BOUND" ] || [ "$reason" = "REBOOT" ]; then + # If we have $new_rfc3442_classless_static_routes then we have to + # ignore $new_routers entirely. + if [ ! "$new_rfc3442_classless_static_routes" ]; then + # Set if_metric if IF_METRIC is set or there's more than one router. + if_metric="$IF_METRIC" + if [ "${new_routers%% *}" != "${new_routers}" ]; then + if_metric=${if_metric:-1} + fi + + for router in $new_routers; do + if [ "$new_subnet_mask" = "255.255.255.255" ]; then + # Set explicit route for p2p connection. + ip -4 route add table ${table_id} ${router} dev $interface >/dev/null 2>&1 + fi + + # Remove old default route should it remain from dhclient-script. + ip -4 route del default via ${router} dev ${interface} \ + ${if_metric:+metric $if_metric} >/dev/null 2>&1 + + # Set default route. + ip -4 route add table ${table_id} default via ${router} dev ${interface} \ + ${if_metric:+metric $if_metric} >/dev/null 2>&1 + + if [ -n "$if_metric" ]; then + if_metric=$((if_metric+1)) + fi + done + else + set -- $new_rfc3442_classless_static_routes + + while [ $# -gt 0 ]; do + net_length=$1 + via_arg='' + + case $net_length in + 32|31|30|29|28|27|26|25) + if [ $# -lt 9 ]; then + return 1 + fi + net_address="${2}.${3}.${4}.${5}" + gateway="${6}.${7}.${8}.${9}" + shift 9 + ;; + 24|23|22|21|20|19|18|17) + if [ $# -lt 8 ]; then + return 1 + fi + net_address="${2}.${3}.${4}.0" + gateway="${5}.${6}.${7}.${8}" + shift 8 + ;; + 16|15|14|13|12|11|10|9) + if [ $# -lt 7 ]; then + return 1 + fi + net_address="${2}.${3}.0.0" + gateway="${4}.${5}.${6}.${7}" + shift 7 + ;; + 8|7|6|5|4|3|2|1) + if [ $# -lt 6 ]; then + return 1 + fi + net_address="${2}.0.0.0" + gateway="${3}.${4}.${5}.${6}" + shift 6 + ;; + 0) # default route + if [ $# -lt 5 ]; then + return 1 + fi + net_address="0.0.0.0" + gateway="${2}.${3}.${4}.${5}" + shift 5 + ;; + *) # error + return 1 + ;; + esac + + # Take care of link-local routes. + if [ "${gateway}" != '0.0.0.0' ]; then + via_arg="via ${gateway}" + fi + + # Set route (ip detects host routes automatically). + ip -4 route add table ${table_id} "${net_address}/${net_length}" \ + ${via_arg} dev "${interface}" >/dev/null 2>&1 + done + fi + fi + + if [ -n "$alias_ip_address" ] && + [ "$new_ip_address" != "$alias_ip_address" ]; then + ip -4 route add table ${table_id} ${alias_ip_address} dev ${interface} >/dev/null 2>&1 + fi + ;; + + EXPIRE|FAIL|RELEASE|STOP) + if [ -n "$alias_ip_address" ]; then + ip -4 route add table ${table_id} ${alias_ip_address} dev ${interface} >/dev/null 2>&1 + fi + + ;; + + TIMEOUT) + # If there is no router recorded in the lease or the 1st router answers pings. + if [ -z "$new_routers" ] || ping -q -c 1 "${new_routers%% *}"; then + # If we have $new_rfc3442_classless_static_routes then we have to + # ignore $new_routers entirely. + if [ ! "$new_rfc3442_classless_static_routes" ]; then + if [ -n "$alias_ip_address" ] && + [ "$new_ip_address" != "$alias_ip_address" ]; then + ip -4 route add table ${table_id} ${alias_ip_address} dev ${interface} >/dev/null 2>&1 + fi + + # Set default route. + for router in $new_routers; do + ip -4 route add table ${table_id} default via ${router} dev ${interface} \ + ${if_metric:+metric $if_metric} >/dev/null 2>&1 + + if [ -n "$if_metric" ]; then + if_metric=$((if_metric+1)) + fi + done + fi + fi + + ;; +esac + +fi