blob: cbfad99bce2522143c6f5c536dba2226536d03b0 [file] [log] [blame]
# SPDX-FileCopyrightText: 2022-present Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from mininet.node import Host, Node
import socket
import struct
DBUF_DROP_TIMEOUT_SEC = "30s"
DBUF_NUM_QUEUES = 10
DBUF_MAX_PKTS_PER_QUEUE = 16
def ip2long(ip):
"""
Convert an IP string to long
"""
packedIP = socket.inet_aton(ip)
return struct.unpack("!L", packedIP)[0]
class IPv4Host(Host):
"""Host that can be configured with an IPv4 gateway (default route).
"""
def config(self, mac=None, ip=None, defaultRoute=None, lo='up', gw=None, **_params):
super(IPv4Host, self).config(mac, ip, defaultRoute, lo, **_params)
self.cmd('ip -4 addr flush dev %s' % self.defaultIntf())
self.cmd('ip -6 addr flush dev %s' % self.defaultIntf())
self.cmd('sysctl -w net.ipv4.ip_forward=0')
self.cmd('ip -4 link set up %s' % self.defaultIntf())
self.cmd('ip -4 addr add %s dev %s' % (ip, self.defaultIntf()))
if gw:
self.cmd('ip -4 route add default via %s' % gw)
# Disable offload
for attr in ["rx", "tx", "sg"]:
cmd = "/sbin/ethtool --offload %s %s off" % (self.defaultIntf(), attr)
self.cmd(cmd)
def updateIP():
return ip.split('/')[0]
self.defaultIntf().updateIP = updateIP
class TaggedIPv4Host(Host):
"""VLAN-tagged host that can be configured with an IPv4 gateway
(default route).
"""
vlanIntf = None
def config(self, mac=None, ip=None, defaultRoute=None, lo='up', gw=None,
vlan=None, **_params):
super(TaggedIPv4Host, self).config(mac, ip, defaultRoute, lo, **_params)
self.vlanIntf = "%s.%s" % (self.defaultIntf(), vlan)
# Replace default interface with a tagged one
self.cmd('ip -4 addr flush dev %s' % self.defaultIntf())
self.cmd('ip -6 addr flush dev %s' % self.defaultIntf())
self.cmd('ip -4 link add link %s name %s type vlan id %s' % (
self.defaultIntf(), self.vlanIntf, vlan))
self.cmd('ip -4 link set up %s' % self.vlanIntf)
self.cmd('ip -4 addr add %s dev %s' % (ip, self.vlanIntf))
if gw:
self.cmd('ip -4 route add default via %s' % gw)
self.defaultIntf().name = self.vlanIntf
self.nameToIntf[self.vlanIntf] = self.defaultIntf()
# Disable offload
for attr in ["rx", "tx", "sg"]:
cmd = "/sbin/ethtool --offload %s %s off" % (
self.defaultIntf(), attr)
self.cmd(cmd)
def updateIP():
return ip.split('/')[0]
self.defaultIntf().updateIP = updateIP
def terminate(self):
self.cmd('ip -4 link remove link %s' % self.vlanIntf)
super(TaggedIPv4Host, self).terminate()
class DbufHost(IPv4Host):
def __init__(self, name, inNamespace=False, **params):
super(DbufHost, self).__init__(name, inNamespace, **params)
def config(self, drainIp=None, drainMac=None, **_params):
super(DbufHost, self).config(**_params)
self.setDrainIpAndMac(self.defaultIntf(), drainIp, drainMac)
self.startDbuf()
def startDbuf(self):
args = map(str, [
"-max_queues",
DBUF_NUM_QUEUES,
"-max_packet_slots_per_queue",
DBUF_MAX_PKTS_PER_QUEUE,
"-queue_drop_timeout",
DBUF_DROP_TIMEOUT_SEC,
])
# Send to background
cmd = '/usr/local/bin/dbuf %s > /tmp/dbuf_%s.log 2>&1 &' \
% (" ".join(args), self.name)
print(cmd)
self.cmd(cmd)
def setDrainIpAndMac(self, intf, drainIp=None, drainMac=None):
if drainIp:
self.setHostRoute(drainIp, intf)
if drainMac:
self.setARP(drainIp, drainMac)
class DualHomedIpv4Host(Host):
"""A dual homed host that can be configured with an IPv4 gateway (default route).
"""
def __init__(self, name, **kwargs):
super(DualHomedIpv4Host, self).__init__(name, **kwargs)
self.bond0 = None
def config(self, ip=None, gw=None, **kwargs):
super(DualHomedIpv4Host, self).config(**kwargs)
intf0 = self.intfs[0].name
intf1 = self.intfs[1].name
self.bond0 = "%s-bond0" % self.name
self.cmd('modprobe bonding')
self.cmd('ip link add %s type bond miimon 100 mode balance-xor xmit_hash_policy layer2+3' %
self.bond0)
self.cmd('ip link set %s down' % intf0)
self.cmd('ip link set %s down' % intf1)
self.cmd('ip link set %s master %s' % (intf0, self.bond0))
self.cmd('ip link set %s master %s' % (intf1, self.bond0))
self.cmd('ip addr flush dev %s' % intf0)
self.cmd('ip addr flush dev %s' % intf1)
self.cmd('ip link set %s up' % self.bond0)
self.cmd('sysctl -w net.ipv4.ip_forward=0')
self.cmd('ip -4 addr add %s dev %s' % (ip, self.bond0))
if gw:
self.cmd('ip -4 route add default via %s' % gw)
# Disable offload
for attr in ["rx", "tx", "sg"]:
cmd = "/sbin/ethtool --offload %s %s off" % (self.defaultIntf(), attr)
self.cmd(cmd)
def terminate(self, **kwargs):
self.cmd('ip link set %s down' % self.bond0)
self.cmd('ip link delete %s' % self.bond0)
super(DualHomedIpv4Host, self).terminate()
class DualHomedDbufHost(DualHomedIpv4Host, DbufHost):
def __init__(self, name, inNamespace=False, **params):
super(DualHomedDbufHost, self).__init__(name, inNamespace=inNamespace, **params)
def config(self, drainIp=None, drainMac=None, **_params):
super(DualHomedDbufHost, self).config(**_params)
self.setDrainIpAndMac(self.bond0, drainIp, drainMac)