summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2014-04-24 10:27:38 +0900
committerLorenzo Colitti <lorenzo@google.com>2015-02-02 17:47:27 +0900
commit71f0b6211d9550ae267af2603a61789aa680cd28 (patch)
tree46d0f28a81a4fd863adfd4f21b6d6c695fcbb451
parent82be6b9451bfa9e131e5a7f9e5eaf40236a3a2fa (diff)
downloadextras-71f0b6211d9550ae267af2603a61789aa680cd28.tar.gz
Test raw sockets as well, using GRE packets.
Change-Id: Ifaa8adee811d952570cb8d8ae6ce2f6fad6dad00
-rwxr-xr-xtests/net_test/mark_test.py35
-rwxr-xr-xtests/net_test/net_test.py12
2 files changed, 40 insertions, 7 deletions
diff --git a/tests/net_test/mark_test.py b/tests/net_test/mark_test.py
index 69a3a036..b14d48b3 100755
--- a/tests/net_test/mark_test.py
+++ b/tests/net_test/mark_test.py
@@ -166,6 +166,15 @@ class Packets(object):
flags=cls.TCP_ACK | cls.TCP_FIN, window=cls.TCP_WINDOW))
@classmethod
+ def GRE(cls, version, srcaddr, dstaddr, proto, packet):
+ if version == 4:
+ ip = scapy.IP(src=srcaddr, dst=dstaddr, proto=net_test.IPPROTO_GRE)
+ else:
+ ip = scapy.IPv6(src=srcaddr, dst=dstaddr, nh=net_test.IPPROTO_GRE)
+ packet = ip / scapy.GRE(proto=proto) / packet
+ return ("GRE packet", packet)
+
+ @classmethod
def ICMPPortUnreachable(cls, version, srcaddr, dstaddr, packet):
if version == 4:
# Linux hardcodes the ToS on ICMP errors to 0xc0 or greater because of
@@ -773,6 +782,25 @@ class MarkTest(MultiNetworkTest):
self.ExpectPacketOn(netid, msg % "connect/send", expected)
s.close()
+ def CheckRawGrePacket(self, version, netid, routing_mode, dstaddr):
+ s = self.BuildSocket(version, net_test.RawGRESocket, netid, routing_mode)
+
+ inner_version = {4: 6, 6: 4}[version]
+ inner_src = self.MyAddress(inner_version, netid)
+ inner_dst = self._GetRemoteAddress(inner_version)
+ inner = str(Packets.UDP(inner_version, inner_src, inner_dst, sport=None)[1])
+
+ ethertype = {4: net_test.ETH_P_IP, 6: net_test.ETH_P_IPV6}[inner_version]
+ # A GRE header can be as simple as two zero bytes and the ethertype.
+ packet = struct.pack("!i", ethertype) + inner
+ myaddr = self.MyAddress(version, netid)
+
+ s.sendto(packet, (dstaddr, IPPROTO_GRE))
+ desc, expected = Packets.GRE(version, myaddr, dstaddr, ethertype, inner)
+ msg = "Raw IPv%d GRE with inner IPv%d UDP: expected %s on %s" % (
+ version, inner_version, desc, self.GetInterfaceName(netid))
+ self.ExpectPacketOn(netid, msg, expected)
+
def CheckOutgoingPackets(self, routing_mode):
v4addr = self.IPV4_ADDR
v6addr = self.IPV6_ADDR
@@ -794,6 +822,13 @@ class MarkTest(MultiNetworkTest):
self.CheckUDPPacket(6, netid, routing_mode, v6addr)
self.CheckUDPPacket(6, netid, routing_mode, v4mapped)
+ # Creating raw sockets on non-root UIDs requires properly setting
+ # capabilities, which is hard to do from Python.
+ # IP_UNICAST_IF is not supported on raw sockets.
+ if routing_mode not in ["uid", "ucast_oif"]:
+ self.CheckRawGrePacket(4, netid, routing_mode, v4addr)
+ self.CheckRawGrePacket(6, netid, routing_mode, v6addr)
+
def testMarkRouting(self):
"""Checks that socket marking selects the right outgoing interface."""
self.CheckOutgoingPackets("mark")
diff --git a/tests/net_test/net_test.py b/tests/net_test/net_test.py
index 7e8813c0..932a4af6 100755
--- a/tests/net_test/net_test.py
+++ b/tests/net_test/net_test.py
@@ -19,6 +19,7 @@ SO_MARK = 36
IPV6_FLOWLABEL_MGR = 32
IPV6_FLOWINFO_SEND = 33
+ETH_P_IP = 0x0800
ETH_P_IPV6 = 0x86dd
SIOCSIFHWADDR = 0x8924
@@ -46,6 +47,8 @@ IPV6_SEQ_DGRAM_HEADER = (" sl "
"st tx_queue rx_queue tr tm->when retrnsmt"
" uid timeout inode ref pointer drops\n")
+IPPROTO_GRE = 47
+
def SetSocketTimeout(sock, ms):
s = ms / 1000
@@ -102,13 +105,8 @@ def UDPSocket(family):
return Socket(family, SOCK_DGRAM, IPPROTO_UDP)
-def IPv6PacketSocket():
- return Socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6))
-
-
-def IPv4RawSocket(protocol):
- s = Socket(AF_INET, SOCK_RAW, protocol)
- s.setsockopt(SOL_IP, IP_HDRINCL, 1)
+def RawGRESocket(family):
+ s = Socket(family, SOCK_RAW, IPPROTO_GRE)
return s