Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support of OSPFv3 #401

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Support of OSPFv3 #401

wants to merge 10 commits into from

Conversation

rudranil-das
Copy link
Contributor

@rudranil-das rudranil-das commented Jan 29, 2025

Redocly Link: https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/open-traffic-generator/models/ospfv3/artifacts/openapi.yaml&nocors

OTG-PORT-1-OSPFv3 <-----------------------> DUT <-------------------------> OTG-PORT-2-OSPFv3

func Ospfv2P2PRoutesConfig(client *api.ApiClient, routes uint32) gosnappi.Config {
	config := gosnappi.NewConfig()

	// add ports
	p1 := config.Ports().Add().SetName("p1").SetLocation(opts.IxiaCPorts()[0])
	p2 := config.Ports().Add().SetName("p2").SetLocation(opts.IxiaCPorts()[1])

	// add devices
	d1 := config.Devices().Add().SetName("p1d1")
	d2 := config.Devices().Add().SetName("p2d1")

	// add protocol stacks for device d1
	d1Eth1 := d1.Ethernets().
		Add().
		SetName("p1d1Eth1").
		SetMac("00:00:01:01:01:01").
		SetMtu(1500)

	d1Eth1.Connection().SetPortName(p1.Name())

	d1Eth1.
		Ipv6Addresses().
		Add().
		SetName("p1d1ipv6").
		SetAddress("1:1:1::2").
		SetGateway("1:1:1::1").
		SetPrefix(128)

	/* Ospfv3 router configuration on port 1 */

	d1ospfv3 := d1.Ospfv3().
		SetName("p1d1ospfv3").
		SetRouterId("1.1.1.2")

	// Enable optional Learned Information filter
	d1ospfv3.SetStoreLsa(true)

	// Set optional timers
	d1ospfv3.
		SetLsaRetransmitTime(1).
		SetLsaRefreshTime(5).
		SetInterBurstLsuInterval(50)

	// Set optional graceful restart mode
	d1ospfv3.GracefulRestart().SetHelperMode(true)

	// Set optional capabilities parameters.
	d1ospfv3.Capabilities().
		SetLsaBBit(true).
		SetLsaEBit(true)

	// Ospfv3 Interface
	d1ospfv3Intf := d1ospfv3.Interfaces().Add().SetName("p1d1int").
		SetIpv6Name("p1d1ipv6")

	d1ospfv3Intf.Area().SetIp("1.1.1.2")
	// d1ospfv3Intf.Area().SetId(1)

	d1ospfv3Intf.NetworkType().PointToPoint()

	// Change Hello timers default values.
	d1ospfv3Intf.Capabilities().
		SetHelloInterval(20).
		SetDeadInterval(60).
		SetLinkMetric(1).
		SetPriority(20).
		SetValidateReceivedMtu(true)

	//v6 routes
	d1ospfv3v6route := d1ospfv3.
		V6Routes().
		Add().
		SetName("p1d1rr1_v6routes").SetMetric(10)

	d1ospfv3v6route.
		Addresses().
		Add().
		SetAddress("4:4:4::1").
		SetPrefix(128).
		SetCount(5).
		SetStep(1)

	// Set route-origin
	d1ospfv3v6route.RouteOrigin().
		NssaExternal().
		ForwardingAddress().InterfaceIp()

	// add protocol stacks for device d2
	d2Eth1 := d2.Ethernets().
		Add().
		SetName("p2d1Eth1").
		SetMac("00:00:02:02:02:02").
		SetMtu(1500)

	d2Eth1.Connection().SetPortName(p2.Name())

	d2Eth1.
		Ipv6Addresses().
		Add().
		SetName("p2d1ipv6").
		SetAddress("2:2:2::2").
		SetGateway("2:2:2::1").
		SetPrefix(128)

	/* Ospfv3 router configuration on port 2 */

	d2ospfv3 := d1.Ospfv3().
		SetName("p2d1ospfv3").
		SetRouterId("2.2.2.2")

	// Enable optional Learned Information filter
	d2ospfv3.SetStoreLsa(true)

	// Set optional timers
	d2ospfv3.
		SetLsaRetransmitTime(1).
		SetLsaRefreshTime(5).
		SetInterBurstLsuInterval(50)

	// Set optional graceful restart mode
	d2ospfv3.GracefulRestart().SetHelperMode(true)

	// Set optional capabilities parameters.
	d2ospfv3.Capabilities().
		SetLsaBBit(true).
		SetLsaEBit(true)

	// Ospfv3 Interface
	d2ospfv3Intf := d2ospfv3.Interfaces().Add().SetName("p2d1int").
		SetIpv6Name("p2d1ipv6")

	d2ospfv3Intf.Area().SetIp("2.2.2.2")

	d2ospfv3Intf.NetworkType().PointToPoint()

	// Change Hello timers default values.
	d2ospfv3Intf.Capabilities().
		SetHelloInterval(20).
		SetDeadInterval(60).
		SetLinkMetric(1).
		SetPriority(20).
		SetValidateReceivedMtu(true)

	//v6 routes
	d2ospfv3v6route := d2ospfv3.
		V6Routes().
		Add().
		SetName("p2d2rr1_v6routes").SetMetric(10)

	d2ospfv3v6route.
		Addresses().
		Add().
		SetAddress("6:6:6::1").
		SetPrefix(128).
		SetCount(5).
		SetStep(1)

	// Set route-origin
	d2ospfv3v6route.RouteOrigin().
		NssaExternal().
		ForwardingAddress().InterfaceIp()

	// Flows config

	{ // Add endpoints and packet description for flow 1
		flow1 := config.Flows().Add()
		flow1.
			SetName("IPv4 " + p1.Name() + "-> " + p2.Name()).
			TxRx().
			Device().
			SetTxNames([]string{d1ospfv3v6route.Name()}).
			SetRxNames([]string{d2ospfv3v6route.Name()})
		flow1.Metrics().SetEnable(true)
		flow1.Duration().FixedPackets().SetPackets(1000)
		flow1.Rate().SetPps(200)
		//ethernet
		flow1Eth := flow1.Packet().Add().Ethernet()
		flow1Eth.Src().SetValue(d1Eth1.Mac())
		flow1Eth.Dst().Auto()
		//IP packet
		flow1Ip := flow1.Packet().Add().Ipv4()
		flow1Ip.Src().Increment().SetStart(d1ospfv3v6route.Addresses().Items()[0].Address())
		flow1Ip.Src().Increment().SetStep("0.0.0.1")
		flow1Ip.Src().Increment().SetCount(5)
		flow1Ip.Dst().Increment().SetStart(d2ospfv3v6route.Addresses().Items()[0].Address())
		flow1Ip.Dst().Increment().SetStep("0.0.0.1")
		flow1Ip.Dst().Increment().SetCount(5)
	}

	{ // Add endpoints and packet description for flow 2
		flow2 := config.Flows().Add()
		flow2.
			SetName("IPv4 " + p2.Name() + "-> " + p1.Name()).
			TxRx().
			Device().
			SetTxNames([]string{d2ospfv3v6route.Name()}).
			SetRxNames([]string{d1ospfv3v6route.Name()})

		flow2.Metrics().SetEnable(true)
		flow2.Duration().FixedPackets().SetPackets(1000)
		flow2.Rate().SetPps(200)
		//ethernet
		flow2Eth := flow2.Packet().Add().Ethernet()
		flow2Eth.Src().SetValue(d1Eth1.Mac())
		flow2Eth.Dst().Auto()
		//IP packet
		flow2Ip := flow2.Packet().Add().Ipv4()
		flow2Ip.Src().Increment().SetStart(d2ospfv3v6route.Addresses().Items()[0].Address())
		flow2Ip.Src().Increment().SetStep("0.0.0.1")
		flow2Ip.Src().Increment().SetCount(5)
		flow2Ip.Dst().Increment().SetStart(d1ospfv3v6route.Addresses().Items()[0].Address())
		flow2Ip.Dst().Increment().SetStep("0.0.0.1")
		flow2Ip.Dst().Increment().SetCount(5)
	}

	return config
}

@rudranil-das rudranil-das marked this pull request as draft January 29, 2025 16:46
@rudranil-das rudranil-das self-assigned this Jan 29, 2025
@rudranil-das rudranil-das marked this pull request as ready for review February 4, 2025 08:05
Copy link
Contributor

@SuryyaKrJana SuryyaKrJana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall looks ok similar to ospfv2. RFC references at some places are good to have.

status: under_review
information: OSPFv3 is currently under review for pending exploration on use cases.
type: object
required: [name, router_id, interfaces]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

router id can be choice of ipv6 intf or custom ipv6 address and with default interface-ip. so required field can be excluded.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Router id is 32 bit so cannot point to ipv6 intf . But can have a auto choice where first IPv4 addess on the router is used. If none are available for use, implementation should return an error. This is possible to keep an auto option.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 'auto' option. Keeping comment open as reminder to clarify implementation choices around the 'auto' option.

Copy link
Contributor

@apratimmukherjee apratimmukherjee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial review . Main issue : Support of multi-instances .
Secondary : Impact of route config in router with multiple interfaces of different types of areas ( also relevant for OSPFv2 probably ) .

format: uint32
default: 10
x-field-uid: 3
priority:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe priority can be clubbed with broadcast type of link since it is actually not a relevant field for p2p type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping it open to clarify impact on UX.

status: under_review
information: OSPFv3 is currently under review for pending exploration on use cases.
type: object
required: [name, router_id, interfaces]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Router id is 32 bit so cannot point to ipv6 intf . But can have a auto choice where first IPv4 addess on the router is used. If none are available for use, implementation should return an error. This is possible to keep an auto option.

When used in Hello packets, the Options field allows a router to reject a neighbor because of a capability mismatch.
type: object
properties:
dc_bit:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these bits should probably be in the router level in the model , considering multiple interfaces. Need to check RFC once on which bits MUST be same across multiple interfaces and which are truly per interface information.

information: OSPFv3 is currently under review for pending exploration on use cases.
type: object
required: [name, router_id, interfaces]
properties:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we need to start with array of instances and then have router within it. Otherwise we will not be able to support OSPFv3 Multi instance in any reasonable way.

x-field-uid: 3
external_type_2:
x-field-uid: 4
nssa_external:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to clarify how to setup NSSA areas , probably need non zero area id + NSSA capability + external type routes should not be sent in the positive test case .. maybe need a warning from implementation etc . Basically thinking about impact of multiple interfaces in the model, some say area 0 and some area 1 with or without nssa , user will probably not be able to emulate sending specific routes for specific interfaces depending on type .. for now with single interface it is fine but might not scale well with true multiple interfaces. Need some tests to work out correct model for this. Might need to push routes to interface OR clarify in routes that either routes will be converted to NSSA or External if type mismatches or NSSA interfaces will not transmit External routes etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants