-
Notifications
You must be signed in to change notification settings - Fork 757
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 LWTUNNEL_ENCAP_SEG6 #282
Conversation
Hi. Let me know if there is any modification I should make for this change. Thanks! |
nl/seg6_linux.go
Outdated
if len(s1.Segments) != len(s2.Segments) { | ||
return false | ||
} | ||
if len(s1.Segments) != 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comment: This if
check is not really needed, if no segments are there, the for
loop will be a no op.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review. I will remove this if
.
nl/seg6_linux.go
Outdated
b[9] = srh.flags | ||
native.PutUint16(b[10:], srh.reserved) | ||
for _, netIP := range srh.Segments { | ||
b = append(b, netIP.To16()...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why to16()
? The function is for representing a 4 byte IPv4 address into the 16 bytes IPv4 in IPv6 notation.
Being srh
of type Ipv6SrHdr
, I was expecting its segments to be already IPv6 addresses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Will change to b = append(b, netIP...)
.
nl/seg6_linux.go
Outdated
"net" | ||
) | ||
|
||
type Ipv6SrHdr struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: I think IP
should be capitalized IPv6SrHdr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Will change to IPv6SrHdr
.
nl/seg6_linux.go
Outdated
type Ipv6SrHdr struct { | ||
nexthdr uint8 | ||
hdrlen uint8 | ||
typ uint8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: To avoid using the reserved type
string, can you please rename this field to routingType
?
I know it is an internal field, but I am not sure typ
would directly convey what it represents to somebody reading the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed what's used as temp var in MPLS code.
But yes, routingType
should be easier to understand as a name of IPv6SrHdr
member.
I changed ones in nl/seg6_linux.go
to routingType
.
I kept ones in route_linux.go
as is typ
since they are temp var used very close to where defined by :=
.
route_linux.go
Outdated
if !ok { | ||
return false | ||
} | ||
if e == nil && o == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very minor: This could be replaced by
if e == o {
return true
}
it would also avoid the subsequent field by field comparison on same object comparison call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. Very educational. Will change it.
nl/seg6_linux.go
Outdated
) | ||
|
||
type Ipv6SrHdr struct { | ||
nexthdr uint8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This project in most parts seems to be following the convention of CamelCase naming.
Please avoid underscore in structure field names and change this one to something like hdrLen
or headerLen
what you prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to below.
type IPv6SrHdr struct {
nextHdr uint8
hdrLen uint8
routingType uint8
segmentsLeft uint8
firstSegment uint8
nl/seg6_linux.go
Outdated
native.PutUint32(b, uint32(mode)) | ||
srh.nexthdr = 0 // use 0 when calling netlink | ||
srh.hdrlen = uint8(16 * nsegs >> 3) // in 8-octets unit | ||
srh.typ = 4 // Routing Type to be assigned by IANA (suggested value: 4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we have a constant for this as does the kernel code
#define IPV6_SRCRT_TYPE_4 4 /* Segment Routing with IPv6 */
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defined them in nl/syscall.go
// routing header types
const (
IPV6_SRCRT_STRICT = 0x01 // Deprecated; will be removed
IPV6_SRCRT_TYPE_0 = 0 // Deprecated; will be removed
IPV6_SRCRT_TYPE_2 = 2 // IPv6 type 2 Routing Header
IPV6_SRCRT_TYPE_4 = 4 // Segment Routing with IPv6
)
And changed to: srh.routingType = IPV6_SRCRT_TYPE_4 // Routing Type assigned by IANA
nl/seg6_linux.go
Outdated
err := fmt.Errorf("DecodeSEG6Encap: Error parsing Segment List (buf len: %d)\n", len(buf)) | ||
return mode, srh, err | ||
} | ||
seglist := make([]net.IP, 0, len(buf)/16) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very minor: We do not need the extra seglist
slice, we could just replace it with srh.Segments
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Removed seglist := make
and modified append line as below:
srh.Segments = append(srh.Segments, net.IP(buf[:16]))
.
route_linux.go
Outdated
} | ||
func (e *SEG6Encap) Decode(buf []byte) error { | ||
if len(buf) < 4 { | ||
return fmt.Errorf("Lack of bytes") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file and other ones in this project seems to be following the go recommendation where the reported error strings start in lower case. Please adhere to this convention here and in the other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I fixed ones in this PR and from MPLS code which had same error message. (ex: "Lack of bytes")
a0f9e2d
to
8d1eb07
Compare
Applied changes based on feedback. Fixed conflict due to syscall -> unix checkin recently done on master. |
route_linux.go
Outdated
// SEG6 definitions | ||
type SEG6Encap struct { | ||
Mode int | ||
Srh nl.IPv6SrHdr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the last thing I am not convinced about.
Seg6Encap
is netlink
pkg user interface, lib client will have to provide it when calling netlink.AddRoute()
.
I am not sure we should have client import netlink/nl
for setting Srh
, as it is done now for convenience I guess, where only its Segments
field is exported.
I took a look at other netlink
pkg API, for the most no netlink/nl
types need to be fed in.
Probably this type could be changed to
type SEG6Encap struct {
Mode int
Segments []net.IP
}
and the respective nl.IPv6SrHdr
could be created internally when interfacing with netlink/nl
methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed to Segments []net.IP
as you suggested.
I removed using IPv6SrHdr
in EncodeSEG6Encap
to make code cleaner and short.
I kept using it in DecodeSEG6Encap
in case one wants to do granular check with func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool
by directly using netlink/nl.
For example, there could be a case that only segmentsLeft
firstSegment
are different for two seg6 route entries. However, explicitly configuring those values via iproute2 is not currently supported. Thus, will leave Encap part for future when someone actually wants to do such operation.
Thank you @ebiken, I have one last comment, otherwise it looks good to me. |
Note: I have run the test and confirmed it pass after the change.
|
Thank you @ebiken, looks good to me. |
Thank you @aboch for many suggestions. |
Added LWTUNNEL_ENCAP_SEG6 support.
With this change, one can do things similar to below iproute2 command.