summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/checker
diff options
context:
space:
mode:
authorRyan Heacock <rheacock@google.com>2020-11-19 18:13:24 -0800
committergVisor bot <gvisor-bot@google.com>2020-11-19 18:15:25 -0800
commitfbc4a8dbd1d1939854dbeb6ccfd4c6267f85c9ec (patch)
tree9a56ce31c4bddc087212837f3094bff8ee44739c /pkg/tcpip/checker
parent9c553f2d4e4b0f2c3d296d0dfac6a31579b60347 (diff)
Perform IGMPv2 when joining IPv4 multicast groups
Added headers, stats, checksum parsing capabilities from RFC 2236 describing IGMPv2. IGMPv2 state machine is implemented for each condition, sending and receiving IGMP Membership Reports and Leave Group messages with backwards compatibility with IGMPv1 routers. Test: * Implemented igmp header parser and checksum calculator in header/igmp_test.go * ipv4/igmp_test.go tests incoming and outgoing IGMP messages and pathways. * Added unit test coverage for IGMPv2 RFC behavior + IGMPv1 backwards compatibility in ipv4/igmp_test.go. Fixes #4682 PiperOrigin-RevId: 343408809
Diffstat (limited to 'pkg/tcpip/checker')
-rw-r--r--pkg/tcpip/checker/checker.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/pkg/tcpip/checker/checker.go b/pkg/tcpip/checker/checker.go
index 81f762e10..1c82c2c3b 100644
--- a/pkg/tcpip/checker/checker.go
+++ b/pkg/tcpip/checker/checker.go
@@ -1227,3 +1227,71 @@ func NDPRSOptions(opts []header.NDPOption) TransportChecker {
ndpOptions(t, rs.Options(), opts)
}
}
+
+// IGMP checks the validity and properties of the given IGMP packet. It is
+// expected to be used in conjunction with other IGMP transport checkers for
+// specific properties.
+func IGMP(checkers ...TransportChecker) NetworkChecker {
+ return func(t *testing.T, h []header.Network) {
+ t.Helper()
+
+ last := h[len(h)-1]
+
+ if p := last.TransportProtocol(); p != header.IGMPProtocolNumber {
+ t.Fatalf("Bad protocol, got %d, want %d", p, header.IGMPProtocolNumber)
+ }
+
+ igmp := header.IGMP(last.Payload())
+ for _, f := range checkers {
+ f(t, igmp)
+ }
+ if t.Failed() {
+ t.FailNow()
+ }
+ }
+}
+
+// IGMPType creates a checker that checks the IGMP Type field.
+func IGMPType(want header.IGMPType) TransportChecker {
+ return func(t *testing.T, h header.Transport) {
+ t.Helper()
+
+ igmp, ok := h.(header.IGMP)
+ if !ok {
+ t.Fatalf("got transport header = %T, want = header.IGMP", h)
+ }
+ if got := igmp.Type(); got != want {
+ t.Errorf("got igmp.Type() = %d, want = %d", got, want)
+ }
+ }
+}
+
+// IGMPMaxRespTime creates a checker that checks the IGMP Max Resp Time field.
+func IGMPMaxRespTime(want byte) TransportChecker {
+ return func(t *testing.T, h header.Transport) {
+ t.Helper()
+
+ igmp, ok := h.(header.IGMP)
+ if !ok {
+ t.Fatalf("got transport header = %T, want = header.IGMP", h)
+ }
+ if got := igmp.MaxRespTime(); got != want {
+ t.Errorf("got igmp.MaxRespTime() = %d, want = %d", got, want)
+ }
+ }
+}
+
+// IGMPGroupAddress creates a checker that checks the IGMP Group Address field.
+func IGMPGroupAddress(want tcpip.Address) TransportChecker {
+ return func(t *testing.T, h header.Transport) {
+ t.Helper()
+
+ igmp, ok := h.(header.IGMP)
+ if !ok {
+ t.Fatalf("got transport header = %T, want = header.IGMP", h)
+ }
+ if got := igmp.GroupAddress(); got != want {
+ t.Errorf("got igmp.GroupAddress() = %s, want = %s", got, want)
+ }
+ }
+}