#!/usr/bin/python3
#
# Copyright 2014 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import cstruct
import ctypes
import errno
import os
import random
from socket import *  # pylint: disable=wildcard-import
import struct
import time           # pylint: disable=unused-import
import unittest

from scapy import all as scapy

import csocket
import iproute
import multinetwork_base
import net_test
import netlink
import packets

# For brevity.
UDP_PAYLOAD = net_test.UDP_PAYLOAD

IPV6_FLOWINFO = 11

SYNCOOKIES_SYSCTL = "/proc/sys/net/ipv4/tcp_syncookies"
TCP_MARK_ACCEPT_SYSCTL = "/proc/sys/net/ipv4/tcp_fwmark_accept"


class OutgoingTest(multinetwork_base.MultiNetworkBaseTest):

  # How many times to run outgoing packet tests.
  ITERATIONS = 5

  def CheckPingPacket(self, version, netid, routing_mode, packet):
    s = self.BuildSocket(version, net_test.PingSocket, netid, routing_mode)

    myaddr = self.MyAddress(version, netid)
    mysockaddr = self.MySocketAddress(version, netid)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    s.bind((mysockaddr, packets.PING_IDENT))
    net_test.SetSocketTos(s, packets.PING_TOS)

    dstaddr = self.GetRemoteAddress(version)
    dstsockaddr = self.GetRemoteSocketAddress(version)
    desc, expected = packets.ICMPEcho(version, myaddr, dstaddr)
    msg = "IPv%d ping: expected %s on %s" % (
        version, desc, self.GetInterfaceName(netid))

    s.sendto(packet + packets.PING_PAYLOAD, (dstsockaddr, 19321))

    self.ExpectPacketOn(netid, msg, expected)
    s.close()

  def CheckTCPSYNPacket(self, version, netid, routing_mode):
    s = self.BuildSocket(version, net_test.TCPSocket, netid, routing_mode)

    myaddr = self.MyAddress(version, netid)
    dstaddr = self.GetRemoteAddress(version)
    dstsockaddr = self.GetRemoteSocketAddress(version)
    desc, expected = packets.SYN(53, version, myaddr, dstaddr,
                                 sport=None, seq=None)


    # Non-blocking TCP connects always return EINPROGRESS.
    self.assertRaisesErrno(errno.EINPROGRESS, s.connect, (dstsockaddr, 53))
    msg = "IPv%s TCP connect: expected %s on %s" % (
        version, desc, self.GetInterfaceName(netid))
    self.ExpectPacketOn(netid, msg, expected)
    s.close()

  def CheckUDPPacket(self, version, netid, routing_mode):
    s = self.BuildSocket(version, net_test.UDPSocket, netid, routing_mode)

    myaddr = self.MyAddress(version, netid)
    dstaddr = self.GetRemoteAddress(version)
    dstsockaddr = self.GetRemoteSocketAddress(version)

    desc, expected = packets.UDP(version, myaddr, dstaddr, sport=None)
    msg = "IPv%s UDP %%s: expected %s on %s" % (
        version, desc, self.GetInterfaceName(netid))

    s.sendto(UDP_PAYLOAD, (dstsockaddr, 53))
    self.ExpectPacketOn(netid, msg % "sendto", expected)

    # IP_UNICAST_IF doesn't seem to work on connected sockets, so no TCP.
    if routing_mode != "ucast_oif":
      s.connect((dstsockaddr, 53))
      s.send(UDP_PAYLOAD)
      self.ExpectPacketOn(netid, msg % "connect/send", expected)

    s.close()

  def CheckRawGrePacket(self, version, netid, routing_mode):
    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 = bytes(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)
    dstaddr = self.GetRemoteAddress(version)

    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)
    s.close()

  def CheckOutgoingPackets(self, routing_mode):
    for _ in range(self.ITERATIONS):
      for netid in self.tuns:

        self.CheckPingPacket(4, netid, routing_mode, self.IPV4_PING)
        # Kernel bug.
        if routing_mode != "oif":
          self.CheckPingPacket(6, netid, routing_mode, self.IPV6_PING)

        # IP_UNICAST_IF doesn't seem to work on connected sockets, so no TCP.
        if routing_mode != "ucast_oif":
          self.CheckTCPSYNPacket(4, netid, routing_mode)
          self.CheckTCPSYNPacket(6, netid, routing_mode)
          self.CheckTCPSYNPacket(5, netid, routing_mode)

        self.CheckUDPPacket(4, netid, routing_mode)
        self.CheckUDPPacket(6, netid, routing_mode)
        self.CheckUDPPacket(5, netid, routing_mode)

        # 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)
          self.CheckRawGrePacket(6, netid, routing_mode)

  def testMarkRouting(self):
    """Checks that socket marking selects the right outgoing interface."""
    self.CheckOutgoingPackets("mark")

  def testUidRouting(self):
    """Checks that UID routing selects the right outgoing interface."""
    self.CheckOutgoingPackets("uid")

  def testOifRouting(self):
    """Checks that oif routing selects the right outgoing interface."""
    self.CheckOutgoingPackets("oif")

  def testUcastOifRouting(self):
    """Checks that ucast oif routing selects the right outgoing interface."""
    self.CheckOutgoingPackets("ucast_oif")

  def CheckRemarking(self, version, use_connect):
    modes = ["mark", "oif", "uid"]
    # Setting UNICAST_IF on connected sockets does not work.
    if not use_connect:
      modes += ["ucast_oif"]

    for mode in modes:
      s = net_test.UDPSocket(self.GetProtocolFamily(version))

      # Figure out what packets to expect.
      sport = net_test.BindRandomPort(version, s)
      dstaddr = {4: self.IPV4_ADDR, 6: self.IPV6_ADDR}[version]
      unspec = {4: "0.0.0.0", 6: "::"}[version]  # Placeholder.
      desc, expected = packets.UDP(version, unspec, dstaddr, sport)

      # If we're testing connected sockets, connect the socket on the first
      # netid now.
      if use_connect:
        netid = list(self.tuns.keys())[0]
        self.SelectInterface(s, netid, mode)
        s.connect((dstaddr, 53))
        expected.src = self.MyAddress(version, netid)

      # For each netid, select that network without closing the socket, and
      # check that the packets sent on that socket go out on the right network.
      #
      # For connected sockets, routing is cached in the socket's destination
      # cache entry. In this case, we check that selecting the network a second
      # time on the same socket (except via SO_BINDTODEVICE, or SO_MARK on 5.0+
      # kernels) does not change routing, but that subsequently invalidating the
      # destination cache entry does. This is a bug in the kernel because
      # re-selecting the netid should cause routing to change, and future
      # kernels may fix this bug for per-UID routing and ucast_oif routing like
      # they already have for mark-based routing. But until they do, this
      # behaviour provides a convenient way to check that InvalidateDstCache
      # actually works.
      prevnetid = None
      for netid in self.tuns:
        self.SelectInterface(s, netid, mode)
        if not use_connect:
          expected.src = self.MyAddress(version, netid)

        def ExpectSendUsesNetid(netid):
          connected_str = "Connected" if use_connect else "Unconnected"
          msg = "%s UDPv%d socket remarked using %s: expecting %s on %s" % (
              connected_str, version, mode, desc, self.GetInterfaceName(netid))
          if use_connect:
            s.send(UDP_PAYLOAD)
          else:
            s.sendto(UDP_PAYLOAD, (dstaddr, 53))
          self.ExpectPacketOn(netid, msg, expected)

        # Does this socket have a stale dst cache entry that we need to clear?
        def SocketHasStaleDstCacheEntry():
          if not prevnetid:
            # This is the first time we're marking the socket.
            return False
          if not use_connect:
            # Non-connected sockets never have dst cache entries.
            return False
          if mode in ["uid", "ucast_oif"]:
            # No kernel invalidates the dst cache entry if the UID or the
            # UCAST_OIF socket option changes.
            return True
          if mode == "oif":
            # Changing SO_BINDTODEVICE always invalidates the dst cache entry.
            return False
          if mode == "mark":
            # Changing the mark invalidates the dst cache entry in 5.0+.
            return net_test.LINUX_VERSION < (5, 0, 0)
          raise AssertionError("%s must be one of %s" % (mode, modes))

        if SocketHasStaleDstCacheEntry():
            ExpectSendUsesNetid(prevnetid)
            # ... until we invalidate it.
            self.InvalidateDstCache(version, prevnetid)

        # In any case, future sends must be correct.
        ExpectSendUsesNetid(netid)

        self.SelectInterface(s, None, mode)
        prevnetid = netid

      s.close()

  def testIPv4Remarking(self):
    """Checks that updating the mark on an IPv4 socket changes routing."""
    self.CheckRemarking(4, False)
    self.CheckRemarking(4, True)

  def testIPv6Remarking(self):
    """Checks that updating the mark on an IPv6 socket changes routing."""
    self.CheckRemarking(6, False)
    self.CheckRemarking(6, True)

  def testIPv6StickyPktinfo(self):
    for _ in range(self.ITERATIONS):
      for netid in self.tuns:
        s = net_test.UDPSocket(AF_INET6)

        # Set a flowlabel.
        net_test.SetFlowLabel(s, net_test.IPV6_ADDR, 0xdead)
        s.setsockopt(net_test.SOL_IPV6, net_test.IPV6_FLOWINFO_SEND, 1)

        # Set some destination options.
        nonce = b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c"
        dstopts = b"".join([
            b"\x11\x02",               # Next header=UDP, 24 bytes of options.
            b"\x01\x06", b"\x00" * 6,  # PadN, 6 bytes of padding.
            b"\x8b\x0c",               # ILNP nonce, 12 bytes.
            nonce
        ])
        s.setsockopt(net_test.SOL_IPV6, IPV6_DSTOPTS, dstopts)
        s.setsockopt(net_test.SOL_IPV6, IPV6_UNICAST_HOPS, 255)

        pktinfo = multinetwork_base.MakePktInfo(6, None, self.ifindices[netid])

        # Set the sticky pktinfo option.
        s.setsockopt(net_test.SOL_IPV6, IPV6_PKTINFO, pktinfo)

        # Specify the flowlabel in the destination address.
        s.sendto(UDP_PAYLOAD, (net_test.IPV6_ADDR, 53, 0xdead, 0))

        sport = s.getsockname()[1]
        srcaddr = self.MyAddress(6, netid)
        expected = (scapy.IPv6(src=srcaddr, dst=net_test.IPV6_ADDR,
                               fl=0xdead, hlim=255) /
                    scapy.IPv6ExtHdrDestOpt(
                        options=[scapy.PadN(optdata="\x00\x00\x00\x00\x00\x00"),
                                 scapy.HBHOptUnknown(otype=0x8b,
                                                     optdata=nonce)]) /
                    scapy.UDP(sport=sport, dport=53) /
                    UDP_PAYLOAD)
        msg = "IPv6 UDP using sticky pktinfo: expected UDP packet on %s" % (
            self.GetInterfaceName(netid))
        self.ExpectPacketOn(netid, msg, expected)
        s.close()

  def CheckPktinfoRouting(self, version):
    for _ in range(self.ITERATIONS):
      for netid in self.tuns:
        family = self.GetProtocolFamily(version)
        s = net_test.UDPSocket(family)

        if version == 6:
          # Create a flowlabel so we can use it.
          net_test.SetFlowLabel(s, net_test.IPV6_ADDR, 0xbeef)

          # Specify some arbitrary options.
          # We declare the flowlabel as ctypes.c_uint32 because on a 32-bit
          # Python interpreter an integer greater than 0x7fffffff (such as our
          # chosen flowlabel after being passed through htonl) is converted to
          # long, and _MakeMsgControl doesn't know what to do with longs.
          cmsgs = [
              (net_test.SOL_IPV6, IPV6_HOPLIMIT, 39),
              (net_test.SOL_IPV6, IPV6_TCLASS, 0x83),
              (net_test.SOL_IPV6, IPV6_FLOWINFO, ctypes.c_uint(htonl(0xbeef))),
          ]
        else:
          # Support for setting IPv4 TOS and TTL via cmsg only appeared in 3.13.
          cmsgs = []
          s.setsockopt(net_test.SOL_IP, IP_TTL, 39)
          s.setsockopt(net_test.SOL_IP, IP_TOS, 0x83)

        dstaddr = self.GetRemoteAddress(version)
        self.SendOnNetid(version, s, dstaddr, 53, netid, UDP_PAYLOAD, cmsgs)

        sport = s.getsockname()[1]
        srcaddr = self.MyAddress(version, netid)

        desc, expected = packets.UDPWithOptions(version, srcaddr, dstaddr,
                                                sport=sport)

        msg = "IPv%d UDP using pktinfo routing: expected %s on %s" % (
            version, desc, self.GetInterfaceName(netid))
        self.ExpectPacketOn(netid, msg, expected)

        s.close()

  def testIPv4PktinfoRouting(self):
    self.CheckPktinfoRouting(4)

  def testIPv6PktinfoRouting(self):
    self.CheckPktinfoRouting(6)


class MarkTest(multinetwork_base.InboundMarkingTest):

  def CheckReflection(self, version, gen_packet, gen_reply):
    """Checks that replies go out on the same interface as the original.

    For each combination:
     - Calls gen_packet to generate a packet to that IP address.
     - Writes the packet generated by gen_packet on the given tun
       interface, causing the kernel to receive it.
     - Checks that the kernel's reply matches the packet generated by
       gen_reply.

    Args:
      version: An integer, 4 or 6.
      gen_packet: A function taking an IP version (an integer), a source
        address and a destination address (strings), and returning a scapy
        packet.
      gen_reply: A function taking the same arguments as gen_packet,
        plus a scapy packet, and returning a scapy packet.
    """
    for netid, iif, ip_if, myaddr, remoteaddr in self.Combinations(version):
      # Generate a test packet.
      desc, packet = gen_packet(version, remoteaddr, myaddr)

      # Test with mark reflection enabled and disabled.
      for reflect in [0, 1]:
        self.SetMarkReflectSysctls(reflect)
        # HACK: IPv6 ping replies always do a routing lookup with the
        # interface the ping came in on. So even if mark reflection is not
        # working, IPv6 ping replies will be properly reflected. Don't
        # fail when that happens.
        if reflect or desc == "ICMPv6 echo":
          reply_desc, reply = gen_reply(version, myaddr, remoteaddr, packet)
        else:
          reply_desc, reply = None, None

        msg = self._FormatMessage(iif, ip_if, "reflect=%d" % reflect,
                                  desc, reply_desc)
        self._ReceiveAndExpectResponse(netid, packet, reply, msg)

  def SYNToClosedPort(self, *args):
    return packets.SYN(999, *args)

  def testIPv4ICMPErrorsReflectMark(self):
    self.CheckReflection(4, packets.UDP, packets.ICMPPortUnreachable)

  def testIPv6ICMPErrorsReflectMark(self):
    self.CheckReflection(6, packets.UDP, packets.ICMPPortUnreachable)

  def testIPv4PingRepliesReflectMarkAndTos(self):
    self.CheckReflection(4, packets.ICMPEcho, packets.ICMPReply)

  def testIPv6PingRepliesReflectMarkAndTos(self):
    self.CheckReflection(6, packets.ICMPEcho, packets.ICMPReply)

  def testIPv4RSTsReflectMark(self):
    self.CheckReflection(4, self.SYNToClosedPort, packets.RST)

  def testIPv6RSTsReflectMark(self):
    self.CheckReflection(6, self.SYNToClosedPort, packets.RST)


class TCPAcceptTest(multinetwork_base.InboundMarkingTest):

  MODE_BINDTODEVICE = "SO_BINDTODEVICE"
  MODE_INCOMING_MARK = "incoming mark"
  MODE_EXPLICIT_MARK = "explicit mark"
  MODE_UID = "uid"

  @classmethod
  def setUpClass(cls):
    super(TCPAcceptTest, cls).setUpClass()

    # Open a port so we can observe SYN+ACKs. Since it's a dual-stack socket it
    # will accept both IPv4 and IPv6 connections. We do this here instead of in
    # each test so we can use the same socket every time. That way, if a kernel
    # bug causes incoming packets to mark the listening socket instead of the
    # accepted socket, the test will fail as soon as the next address/interface
    # combination is tried.
    cls.listensocket = net_test.IPv6TCPSocket()
    cls.listenport = net_test.BindRandomPort(6, cls.listensocket)

  def _SetTCPMarkAcceptSysctl(self, value):
    self.SetSysctl(TCP_MARK_ACCEPT_SYSCTL, value)

  def CheckTCPConnection(self, mode, listensocket, netid, version,
                         myaddr, remoteaddr, packet, reply, msg):
    establishing_ack = packets.ACK(version, remoteaddr, myaddr, reply)[1]

    # Attempt to confuse the kernel.
    self.InvalidateDstCache(version, netid)

    self.ReceivePacketOn(netid, establishing_ack)

    # If we're using UID routing, the accept() call has to be run as a UID that
    # is routed to the specified netid, because the UID of the socket returned
    # by accept() is the effective UID of the process that calls it. It doesn't
    # need to be the same UID; any UID that selects the same interface will do.
    with net_test.RunAsUid(self.UidForNetid(netid)):
      s, _ = listensocket.accept()

    try:
      # Check that data sent on the connection goes out on the right interface.
      desc, data = packets.ACK(version, myaddr, remoteaddr, establishing_ack,
                               payload=UDP_PAYLOAD)
      s.send(UDP_PAYLOAD)
      self.ExpectPacketOn(netid, msg + ": expecting %s" % desc, data)
      self.InvalidateDstCache(version, netid)

      # Keep up our end of the conversation.
      ack = packets.ACK(version, remoteaddr, myaddr, data)[1]
      self.InvalidateDstCache(version, netid)
      self.ReceivePacketOn(netid, ack)

      mark = self.GetSocketMark(s)
    finally:
      self.InvalidateDstCache(version, netid)
      s.close()
      self.InvalidateDstCache(version, netid)

    if mode == self.MODE_INCOMING_MARK:
      self.assertEqual(netid, mark & self.NETID_FWMASK,
                        msg + ": Accepted socket: Expected mark %d, got %d" % (
                            netid, mark))
    elif mode != self.MODE_EXPLICIT_MARK:
      self.assertEqual(0, self.GetSocketMark(listensocket))

    # Check the FIN was sent on the right interface, and ack it. We don't expect
    # this to fail because by the time the connection is established things are
    # likely working, but a) extra tests are always good and b) extra packets
    # like the FIN (and retransmitted FINs) could cause later tests that expect
    # no packets to fail.
    desc, fin = packets.FIN(version, myaddr, remoteaddr, ack)
    self.ExpectPacketOn(netid, msg + ": expecting %s after close" % desc, fin)

    desc, finack = packets.FIN(version, remoteaddr, myaddr, fin)
    self.ReceivePacketOn(netid, finack)

    # Since we called close() earlier, the userspace socket object is gone, so
    # the socket has no UID. If we're doing UID routing, the ack might be routed
    # incorrectly. Not much we can do here.
    desc, finackack = packets.ACK(version, myaddr, remoteaddr, finack)
    self.ExpectPacketOn(netid, msg + ": expecting final ack", finackack)

  def CheckTCP(self, version, modes):
    """Checks that incoming TCP connections work.

    Args:
      version: An integer, 4 or 6.
      modes: A list of modes to excercise.
    """
    for syncookies in [0, 2]:
      for mode in modes:
        for netid, iif, ip_if, myaddr, remoteaddr in self.Combinations(version):
          listensocket = self.listensocket
          listenport = listensocket.getsockname()[1]

          accept_sysctl = 1 if mode == self.MODE_INCOMING_MARK else 0
          self._SetTCPMarkAcceptSysctl(accept_sysctl)
          self.SetMarkReflectSysctls(accept_sysctl)

          bound_dev = iif if mode == self.MODE_BINDTODEVICE else None
          self.BindToDevice(listensocket, bound_dev)

          mark = netid if mode == self.MODE_EXPLICIT_MARK else 0
          self.SetSocketMark(listensocket, mark)

          uid = self.UidForNetid(netid) if mode == self.MODE_UID else 0
          os.fchown(listensocket.fileno(), uid, -1)

          # Generate the packet here instead of in the outer loop, so
          # subsequent TCP connections use different source ports and
          # retransmissions from old connections don't confuse subsequent
          # tests.
          desc, packet = packets.SYN(listenport, version, remoteaddr, myaddr)

          if mode:
            reply_desc, reply = packets.SYNACK(version, myaddr, remoteaddr,
                                               packet)
          else:
            reply_desc, reply = None, None

          extra = "mode=%s, syncookies=%d" % (mode, syncookies)
          msg = self._FormatMessage(iif, ip_if, extra, desc, reply_desc)
          reply = self._ReceiveAndExpectResponse(netid, packet, reply, msg)
          if reply:
            self.CheckTCPConnection(mode, listensocket, netid, version, myaddr,
                                    remoteaddr, packet, reply, msg)

  def testBasicTCP(self):
    self.CheckTCP(4, [None, self.MODE_BINDTODEVICE, self.MODE_EXPLICIT_MARK])
    self.CheckTCP(6, [None, self.MODE_BINDTODEVICE, self.MODE_EXPLICIT_MARK])

  def testIPv4MarkAccept(self):
    self.CheckTCP(4, [self.MODE_INCOMING_MARK])

  def testIPv6MarkAccept(self):
    self.CheckTCP(6, [self.MODE_INCOMING_MARK])

  def testIPv4UidAccept(self):
    self.CheckTCP(4, [self.MODE_UID])

  def testIPv6UidAccept(self):
    self.CheckTCP(6, [self.MODE_UID])

  def testIPv6ExplicitMark(self):
    self.CheckTCP(6, [self.MODE_EXPLICIT_MARK])

class RIOTest(multinetwork_base.MultiNetworkBaseTest):
  """Test for IPv6 RFC 4191 route information option

  Relevant kernel commits:
    upstream:
      f104a567e673 ipv6: use rt6_get_dflt_router to get default router in rt6_route_rcv
      bbea124bc99d net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs.

    android-4.9:
      d860b2e8a7f1 FROMLIST: net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs

    android-4.4:
      e953f89b8563 net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs.

    android-4.1:
      84f2f47716cd net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs.

    android-3.18:
      65f8936934fa net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs.

    android-3.10:
      161e88ebebc7 net: ipv6: Add sysctl for minimum prefix len acceptable in RIOs.

  """

  def setUp(self):
    super(RIOTest, self).setUp()
    self.NETID = random.choice(self.NETIDS)
    self.IFACE = self.GetInterfaceName(self.NETID)
    # return sysctls to default values before each test case
    self.SetAcceptRaRtInfoMinPlen(0)
    self.SetAcceptRaRtInfoMaxPlen(0)
    if multinetwork_base.HAVE_ACCEPT_RA_MIN_LFT:
      self.SetAcceptRaMinLft(0)
    if multinetwork_base.HAVE_RA_HONOR_PIO_LIFE:
      self.SetRaHonorPioLife(0)
    if multinetwork_base.HAVE_RA_HONOR_PIO_PFLAG:
      self.SetRaHonorPioPflag(0)

  def GetRoutingTable(self):
    if multinetwork_base.HAVE_AUTOCONF_TABLE:
      return self._TableForNetid(self.NETID)
    else:
      # main table
      return 254

  def SetAcceptRaRtInfoMinPlen(self, plen):
    self.SetSysctl(
        "/proc/sys/net/ipv6/conf/%s/accept_ra_rt_info_min_plen"
        % self.IFACE, plen)

  def GetAcceptRaRtInfoMinPlen(self):
    return int(self.GetSysctl(
        "/proc/sys/net/ipv6/conf/%s/accept_ra_rt_info_min_plen" % self.IFACE))

  def SetAcceptRaRtInfoMaxPlen(self, plen):
    self.SetSysctl(
        "/proc/sys/net/ipv6/conf/%s/accept_ra_rt_info_max_plen"
        % self.IFACE, plen)

  def GetAcceptRaRtInfoMaxPlen(self):
    return int(self.GetSysctl(
        "/proc/sys/net/ipv6/conf/%s/accept_ra_rt_info_max_plen" % self.IFACE))

  def SetAcceptRaMinLft(self, min_lft):
    self.SetSysctl(
        "/proc/sys/net/ipv6/conf/%s/accept_ra_min_lft" % self.IFACE, min_lft)

  def SetRaHonorPioPflag(self, val):
    self.SetSysctl(
        "/proc/sys/net/ipv6/conf/%s/ra_honor_pio_pflag" % self.IFACE, val)

  def GetAcceptRaMinLft(self):
    return int(self.GetSysctl(
        "/proc/sys/net/ipv6/conf/%s/accept_ra_min_lft" % self.IFACE))

  def SetRaHonorPioLife(self, enabled):
    self.SetSysctl(
        "/proc/sys/net/ipv6/conf/%s/ra_honor_pio_life" % self.IFACE, enabled)

  def GetRaHonorPioLife(self):
    return int(self.GetSysctl(
        "/proc/sys/net/ipv6/conf/%s/ra_honor_pio_life" % self.IFACE))

  def SendRIO(self, rtlifetime, plen, prefix, prf):
    options = scapy.ICMPv6NDOptRouteInfo(rtlifetime=rtlifetime, plen=plen,
                                         prefix=prefix, prf=prf)
    self.SendRA(self.NETID, options=(options,))

  def FindRoutesWithDestination(self, destination):
    canonical = net_test.CanonicalizeIPv6Address(destination)
    return [r for _, r in self.iproute.DumpRoutes(6, self.GetRoutingTable())
            if ('RTA_DST' in r and r['RTA_DST'] == canonical)]

  def FindRoutesWithGateway(self):
    return [r for _, r in self.iproute.DumpRoutes(6, self.GetRoutingTable())
            if 'RTA_GATEWAY' in r]

  def CountRoutes(self):
    return len(self.iproute.DumpRoutes(6, self.GetRoutingTable()))

  def GetRouteExpiration(self, route):
    return float(route['RTA_CACHEINFO'].expires) / 100.0

  def AssertExpirationInRange(self, routes, lifetime, epsilon):
    self.assertTrue(routes)
    found = False
    # Assert that at least one route in routes has the expected lifetime
    for route in routes:
      expiration = self.GetRouteExpiration(route)
      if expiration < lifetime - epsilon:
        continue
      if expiration > lifetime + epsilon:
        continue
      found = True
    self.assertTrue(found)

  def DelRA6(self, prefix, plen):
    version = 6
    netid = self.NETID
    table = self._TableForNetid(netid)
    router = self._RouterAddress(netid, version)
    ifindex = self.ifindices[netid]
    self.iproute._Route(version, iproute.RTPROT_RA, iproute.RTM_DELROUTE,
                        table, prefix, plen, router, ifindex, None, None)

  def testSetAcceptRaRtInfoMinPlen(self):
    for plen in range(-1, 130):
      self.SetAcceptRaRtInfoMinPlen(plen)
      self.assertEqual(plen, self.GetAcceptRaRtInfoMinPlen())

  def testSetAcceptRaRtInfoMaxPlen(self):
    for plen in range(-1, 130):
      self.SetAcceptRaRtInfoMaxPlen(plen)
      self.assertEqual(plen, self.GetAcceptRaRtInfoMaxPlen())

  @unittest.skipUnless(multinetwork_base.HAVE_AUTOCONF_TABLE,
                       "need support for per-table autoconf")
  def testZeroRtLifetime(self):
    PREFIX = "2001:db8:8901:2300::"
    RTLIFETIME = 73500
    PLEN = 56
    PRF = 0
    self.SetAcceptRaRtInfoMaxPlen(PLEN)
    self.SendRIO(RTLIFETIME, PLEN, PREFIX, PRF)
    # Give the kernel time to notice our RA
    time.sleep(0.01)
    self.assertTrue(self.FindRoutesWithDestination(PREFIX))
    # RIO with rtlifetime = 0 should remove from routing table
    self.SendRIO(0, PLEN, PREFIX, PRF)
    # Give the kernel time to notice our RA
    time.sleep(0.01)
    self.assertFalse(self.FindRoutesWithDestination(PREFIX))

  def testMinPrefixLenRejection(self):
    PREFIX = "2001:db8:8902:2345::"
    RTLIFETIME = 70372
    PRF = 0
    # sweep from high to low to avoid spurious failures from late arrivals.
    for plen in range(130, 1, -1):
      self.SetAcceptRaRtInfoMinPlen(plen)
      # RIO with plen < min_plen should be ignored
      self.SendRIO(RTLIFETIME, plen - 1, PREFIX, PRF)
    # Give the kernel time to notice our RAs
    time.sleep(0.1)
    # Expect no routes
    routes = self.FindRoutesWithDestination(PREFIX)
    self.assertFalse(routes)

  def testMaxPrefixLenRejection(self):
    PREFIX = "2001:db8:8903:2345::"
    RTLIFETIME = 73078
    PRF = 0
    # sweep from low to high to avoid spurious failures from late arrivals.
    for plen in range(-1, 128, 1):
      self.SetAcceptRaRtInfoMaxPlen(plen)
      # RIO with plen > max_plen should be ignored
      self.SendRIO(RTLIFETIME, plen + 1, PREFIX, PRF)
    # Give the kernel time to notice our RAs
    time.sleep(0.1)
    # Expect no routes
    routes = self.FindRoutesWithDestination(PREFIX)
    self.assertFalse(routes)

  @unittest.skipUnless(multinetwork_base.HAVE_AUTOCONF_TABLE,
                       "need support for per-table autoconf")
  def testSimpleAccept(self):
    PREFIX = "2001:db8:8904:2345::"
    RTLIFETIME = 9993
    PRF = 0
    PLEN = 56
    self.SetAcceptRaRtInfoMinPlen(48)
    self.SetAcceptRaRtInfoMaxPlen(64)
    self.SendRIO(RTLIFETIME, PLEN, PREFIX, PRF)
    # Give the kernel time to notice our RA
    time.sleep(0.01)
    routes = self.FindRoutesWithGateway()
    self.AssertExpirationInRange(routes, RTLIFETIME, 1)
    self.DelRA6(PREFIX, PLEN)

  @unittest.skipUnless(multinetwork_base.HAVE_AUTOCONF_TABLE,
                       "need support for per-table autoconf")
  def testEqualMinMaxAccept(self):
    PREFIX = "2001:db8:8905:2345::"
    RTLIFETIME = 6326
    PLEN = 21
    PRF = 0
    self.SetAcceptRaRtInfoMinPlen(PLEN)
    self.SetAcceptRaRtInfoMaxPlen(PLEN)
    self.SendRIO(RTLIFETIME, PLEN, PREFIX, PRF)
    # Give the kernel time to notice our RA
    time.sleep(0.01)
    routes = self.FindRoutesWithGateway()
    self.AssertExpirationInRange(routes, RTLIFETIME, 1)
    self.DelRA6(PREFIX, PLEN)

  @unittest.skipUnless(multinetwork_base.HAVE_AUTOCONF_TABLE,
                       "need support for per-table autoconf")
  def testZeroLengthPrefix(self):
    PREFIX = "2001:db8:8906:2345::"
    RTLIFETIME = self.RA_VALIDITY * 2
    PLEN = 0
    PRF = 0
    # Max plen = 0 still allows default RIOs!
    self.SetAcceptRaRtInfoMaxPlen(PLEN)
    self.SendRA(self.NETID)
    # Give the kernel time to notice our RA
    time.sleep(0.01)
    default = self.FindRoutesWithGateway()
    self.AssertExpirationInRange(default, self.RA_VALIDITY, 1)
    # RIO with prefix length = 0, should overwrite default route lifetime
    # note that the RIO lifetime overwrites the RA lifetime.
    self.SendRIO(RTLIFETIME, PLEN, PREFIX, PRF)
    # Give the kernel time to notice our RA
    time.sleep(0.01)
    default = self.FindRoutesWithGateway()
    self.AssertExpirationInRange(default, RTLIFETIME, 1)
    self.DelRA6(PREFIX, PLEN)

  @unittest.skipUnless(multinetwork_base.HAVE_AUTOCONF_TABLE,
                       "need support for per-table autoconf")
  def testManyRIOs(self):
    RTLIFETIME = 68012
    PLEN = 56
    PRF = 0
    COUNT = 1000
    baseline = self.CountRoutes()
    self.SetAcceptRaRtInfoMaxPlen(56)
    # Send many RIOs compared to the expected number on a healthy system.
    for i in range(0, COUNT):
      prefix = "2001:db8:%x:1100::" % i
      self.SendRIO(RTLIFETIME, PLEN, prefix, PRF)
    time.sleep(0.1)
    self.assertEqual(COUNT + baseline, self.CountRoutes())
    for i in range(0, COUNT):
      prefix = "2001:db8:%x:1100::" % i
      self.DelRA6(prefix, PLEN)
    # Expect that we can return to baseline config without lingering routes.
    self.assertEqual(baseline, self.CountRoutes())

  # Contextually, testAcceptRa tests do not belong in RIOTest, but as it
  # turns out, RIOTest has all the useful helpers defined for these tests.
  # TODO: Rename test class or merge RIOTest with RATest.
  @unittest.skipUnless(multinetwork_base.HAVE_ACCEPT_RA_MIN_LFT,
                       "need support for accept_ra_min_lft")
  def testAcceptRaMinLftReadWrite(self):
    self.SetAcceptRaMinLft(500)
    self.assertEqual(500, self.GetAcceptRaMinLft())

  @unittest.skipUnless(multinetwork_base.HAVE_RA_HONOR_PIO_LIFE,
                       "need support for ra_honor_pio_life")
  def testRaHonorPioLifeReadWrite(self):
    self.assertEqual(0, self.GetRaHonorPioLife())
    self.SetRaHonorPioLife(1)
    self.assertEqual(1, self.GetRaHonorPioLife())

  @unittest.skipUnless(multinetwork_base.HAVE_RA_HONOR_PIO_LIFE,
                       "need support for ra_honor_pio_life")
  def testRaHonorPioLife(self):
    self.SetRaHonorPioLife(1)

    # Test setup has sent an initial RA -- expire it.
    self.SendRA(self.NETID, routerlft=0, piolft=0)
    time.sleep(0.1) # Give the kernel time to notice our RA

    # Assert that the address was deleted.
    self.assertIsNone(self.MyAddress(6, self.NETID))

  @unittest.skipUnless(multinetwork_base.HAVE_ACCEPT_RA_MIN_LFT,
                       "need support for accept_ra_min_lft")
  def testAcceptRaMinLftRouterLifetime(self):
    self.SetAcceptRaMinLft(500)

    # Test setup has sent an initial RA. Expire it and test that the RA with
    # lifetime 0 deletes the default route.
    self.SendRA(self.NETID, routerlft=0, piolft=0)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertEqual([], self.FindRoutesWithGateway())

    # RA with lifetime 400 is ignored
    self.SendRA(self.NETID, routerlft=400)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertEqual([], self.FindRoutesWithGateway())

    # RA with lifetime 600 is processed
    self.SendRA(self.NETID, routerlft=600)
    time.sleep(0.1) # Give the kernel time to notice our RA
    # SendRA sets routerlft to 0 if HAVE_AUTOCONF_TABLE is false...
    # TODO: Fix this correctly.
    if multinetwork_base.HAVE_AUTOCONF_TABLE:
      self.assertEqual(1, len(self.FindRoutesWithGateway()))

  @unittest.skipUnless(multinetwork_base.HAVE_ACCEPT_RA_MIN_LFT,
                       "need support for accept_ra_min_lft")
  def testAcceptRaMinLftPIOLifetime(self):
    self.SetAcceptRaMinLft(500)

    # Test setup has sent an initial RA -- expire it.
    self.SendRA(self.NETID, routerlft=0, piolft=0)
    time.sleep(0.1) # Give the kernel time to notice our RA
    # Check that the prefix route was deleted.
    prefixroutes = self.FindRoutesWithDestination(self.OnlinkPrefix(6, self.NETID))
    self.assertEqual([], prefixroutes)

    # Sending a 0-lifetime PIO does not cause the address to be deleted, see
    # rfc2462#section-5.5.3.
    address = self.MyAddress(6, self.NETID)
    self.iproute.DelAddress(address, 64, self.ifindices[self.NETID])

    # PIO with lifetime 400 is ignored
    self.SendRA(self.NETID, piolft=400)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertIsNone(self.MyAddress(6, self.NETID))

    # PIO with lifetime 600 is processed
    self.SendRA(self.NETID, piolft=600)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertIsNotNone(self.MyAddress(6, self.NETID))

  @unittest.skipUnless(multinetwork_base.HAVE_ACCEPT_RA_MIN_LFT,
                       "need support for accept_ra_min_lft")
  def testAcceptRaMinLftRIOLifetime(self):
    PREFIX = "2001:db8:8901:2300::"
    PLEN = 64
    PRF = 0

    self.SetAcceptRaRtInfoMaxPlen(PLEN)
    self.SetAcceptRaMinLft(500)

    # RIO with lifetime 400 is ignored
    self.SendRIO(400, PLEN, PREFIX, PRF)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertFalse(self.FindRoutesWithDestination(PREFIX))

    # RIO with lifetime 600 is processed
    self.SendRIO(600, PLEN, PREFIX, PRF)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertTrue(self.FindRoutesWithDestination(PREFIX))

    # RIO with lifetime 0 deletes the route
    self.SendRIO(0, PLEN, PREFIX, PRF)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertFalse(self.FindRoutesWithDestination(PREFIX))

  @unittest.skipUnless(multinetwork_base.HAVE_RA_HONOR_PIO_PFLAG,
                       "needs support for ra_honor_pio_pflag")
  def testPioPflag(self):
    self.SetRaHonorPioPflag(1);

    # Test setup has sent an initial RA -- expire it.
    self.SendRA(self.NETID, routerlft=0, piolft=0)
    time.sleep(0.1) # Give the kernel time to notice our RA
    # Check that the prefix route was deleted.
    prefixroutes = self.FindRoutesWithDestination(self.OnlinkPrefix(6, self.NETID))
    self.assertEqual([], prefixroutes)

    # Sending a 0-lifetime PIO does not cause the address to be deleted, see
    # rfc2462#section-5.5.3.
    address = self.MyAddress(6, self.NETID)
    self.iproute.DelAddress(address, 64, self.ifindices[self.NETID])

    # PIO with p-flag is ignored
    self.SendRA(self.NETID, piopflag=1)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertIsNone(self.MyAddress(6, self.NETID))

    self.SetRaHonorPioPflag(0);
    # PIO with p-flag is processed
    self.SendRA(self.NETID, piopflag=1)
    time.sleep(0.1) # Give the kernel time to notice our RA
    self.assertIsNotNone(self.MyAddress(6, self.NETID))


class RATest(multinetwork_base.MultiNetworkBaseTest):

  ND_ROUTER_ADVERT = 134
  ND_OPT_PIO = 3
  ND_OPT_PREF64 = 38
  NDOptHeader = cstruct.Struct("ndopt_header", "!BB", "type length")
  Pref64Option = cstruct.Struct("pref64_option", "!BBH12s",
                                "type length lft_plc prefix")

  # Android Common Kernels are always based off of an LTS release,
  # skipping this (always failing due to lack of an ACK specific patch) test
  # on Linus's kernels (and various other upstream dev branches) allows
  # for easier testing of Linux rc's and various developer trees.
  @unittest.skipUnless(net_test.IS_STABLE, "not STABLE/LTS kernel")
  def testHasAutoconfTable(self):
    self.assertTrue(multinetwork_base.HAVE_AUTOCONF_TABLE)

  def testDoesNotHaveObsoleteSysctl(self):
    self.assertFalse(os.path.isfile(
        "/proc/sys/net/ipv6/route/autoconf_table_offset"))

  @unittest.skipUnless(multinetwork_base.HAVE_AUTOCONF_TABLE,
                       "no support for per-table autoconf")
  def testPurgeDefaultRouters(self):

    def CheckIPv6Connectivity(expect_connectivity):
      for netid in self.NETIDS:
        s = net_test.UDPSocket(AF_INET6)
        self.SetSocketMark(s, netid)
        if expect_connectivity:
          self.assertTrue(s.sendto(UDP_PAYLOAD, (net_test.IPV6_ADDR, 1234)))
        else:
          self.assertRaisesErrno(errno.ENETUNREACH, s.sendto, UDP_PAYLOAD,
                                 (net_test.IPV6_ADDR, 1234))
        s.close()

    try:
      CheckIPv6Connectivity(True)
      self.SetIPv6SysctlOnAllIfaces("accept_ra", 1)
      self.SetSysctl("/proc/sys/net/ipv6/conf/all/forwarding", 1)
      CheckIPv6Connectivity(False)
    finally:
      self.SetSysctl("/proc/sys/net/ipv6/conf/all/forwarding", 0)
      for netid in self.NETIDS:
        self.SendRA(netid)
      CheckIPv6Connectivity(True)

  def testOnlinkCommunication(self):
    """Checks that on-link communication goes direct and not through routers."""
    for netid in self.tuns:
      # Send a UDP packet to a random on-link destination.
      s = net_test.UDPSocket(AF_INET6)
      iface = self.GetInterfaceName(netid)
      self.BindToDevice(s, iface)
      # dstaddr can never be our address because GetRandomDestination only fills
      # in the lower 32 bits, but our address has 0xff in the byte before that
      # (since it's constructed from the EUI-64 and so has ff:fe in the middle).
      dstaddr = self.GetRandomDestination(self.OnlinkPrefix(6, netid))
      s.sendto(UDP_PAYLOAD, (dstaddr, 53))

      # Expect an NS for that destination on the interface.
      myaddr = self.MyAddress(6, netid)
      mymac = self.MyMacAddress(netid)
      desc, expected = packets.NS(myaddr, dstaddr, mymac)
      msg = "Sending UDP packet to on-link destination: expecting %s" % desc
      time.sleep(0.0001)  # Required to make the test work on kernel 3.1(!)
      self.ExpectPacketOn(netid, msg, expected)

      # Send an NA.
      tgtmac = "02:00:00:00:%02x:99" % netid
      _, reply = packets.NA(dstaddr, myaddr, tgtmac)
      # Don't use ReceivePacketOn, since that uses the router's MAC address as
      # the source. Instead, construct our own Ethernet header with source
      # MAC of tgtmac.
      reply = scapy.Ether(src=tgtmac, dst=mymac) / reply
      self.ReceiveEtherPacketOn(netid, reply)

      # Expect the kernel to send the original UDP packet now that the ND cache
      # entry has been populated.
      sport = s.getsockname()[1]
      desc, expected = packets.UDP(6, myaddr, dstaddr, sport=sport)
      msg = "After NA response, expecting %s" % desc
      self.ExpectPacketOn(netid, msg, expected)

      s.close()

  # This test documents a known issue: routing tables are never deleted.
  @unittest.skipUnless(multinetwork_base.HAVE_AUTOCONF_TABLE,
                       "no support for per-table autoconf")
  def testLeftoverRoutes(self):
    def GetNumRoutes():
      with open("/proc/net/ipv6_route") as ipv6_route:
        return len(ipv6_route.readlines())

    num_routes = GetNumRoutes()
    for i in range(10, 20):
      try:
        self.tuns[i] = self.CreateTunInterface(i)
        self.SendRA(i)
        self.tuns[i].close()
      finally:
        del self.tuns[i]
    self.assertLess(num_routes, GetNumRoutes())

  def SendNdUseropt(self, option):
    options = scapy.ICMPv6NDOptRouteInfo(rtlifetime=rtlifetime, plen=plen,
                                         prefix=prefix, prf=prf)
    self.SendRA(self.NETID, options=(options,))

  def MakePref64Option(self, prefix, lifetime):
    prefix = inet_pton(AF_INET6, prefix)[:12]
    lft_plc = (lifetime & 0xfff8) | 0  # 96-bit prefix length
    return self.Pref64Option((self.ND_OPT_PREF64, 2, lft_plc, prefix))

  def testPref64UserOption(self):
    # Open a netlink socket to receive RTM_NEWNDUSEROPT messages.
    s = netlink.NetlinkSocket(netlink.NETLINK_ROUTE, iproute.RTMGRP_ND_USEROPT)

    # Send an RA with the PREF64 option.
    netid = random.choice(self.NETIDS)
    opt = self.MakePref64Option("64:ff9b::", 300)
    self.SendRA(netid, options=(opt.Pack(),))

    # Check that we get an an RTM_NEWNDUSEROPT message on the socket with the
    # expected option.
    csocket.SetSocketTimeout(s.sock, 100)

    needPIO = multinetwork_base.HAVE_USEROPT_PIO_FIX
    needPref64 = True

    while needPIO or needPref64:
      try:
        data = s._Recv()
      except IOError as e:
        self.fail("Should have received an RTM_NEWNDUSEROPT message. "
                  "Please ensure the kernel supports receiving the "
                  "PREF64 RA option. Error: %s" % e)
      # Check that the message is received correctly.
      nlmsghdr, data = cstruct.Read(data, netlink.NLMsgHdr)
      self.assertEqual(iproute.RTM_NEWNDUSEROPT, nlmsghdr.type)

      # print("data=[%s]\n" % data)

      # Check the option contents.
      ndopthdr, data = cstruct.Read(data, iproute.NdUseroptMsg)
      self.assertEqual(AF_INET6, ndopthdr.family)
      self.assertEqual(self.ND_ROUTER_ADVERT, ndopthdr.icmp_type)
      self.assertEqual(0, ndopthdr.icmp_code)

      self.assertLessEqual(ndopthdr.opts_len, len(data))
      data, leftover = data[:ndopthdr.opts_len], data[ndopthdr.opts_len:]

      # print("ndopthdr=[%s] data=[%s] leftover=[%s]" % (ndopthdr, data, leftover))

      while data:
        # print("data2=[%s]\n" % data)

        header_opt = self.NDOptHeader(data)
        self.assertNotEqual(header_opt.length, 0)
        self.assertLessEqual(header_opt.length * 8, len(data))
        payload, data = data[:header_opt.length * 8], data[header_opt.length * 8:]

        # print("type=%d len=%d payload[%s]\n" % (header_opt.type, header_opt.length * 8, payload))

        if header_opt.type == self.ND_OPT_PIO:
          needPIO = False
        elif header_opt.type == self.ND_OPT_PREF64:
          needPref64 = False
          self.assertEqual(len(opt), len(payload))
          self.assertEqual(opt, self.Pref64Option(payload))
        else:
          # cannot happen: no other options we generate are currently considered user options
          assert False

    # we only ever reach here if we find all options we need
    s.close()

  def testRaFlags(self):
    def GetInterfaceIpv6Flags(iface):
      attrs = self.iproute.GetIflaAfSpecificData(iface, AF_INET6)
      return int(attrs["IFLA_INET6_FLAGS"])

    netid = random.choice(self.NETIDS)
    iface = self.GetInterfaceName(netid)
    expected = iproute.IF_RS_SENT | iproute.IF_RA_RCVD | iproute.IF_READY
    self.assertEqual(expected, GetInterfaceIpv6Flags(iface))

    self.SendRA(netid, m=1, o=0)
    expected |= iproute.IF_RA_MANAGED
    self.assertEqual(expected, GetInterfaceIpv6Flags(iface))

    self.SendRA(netid, m=1, o=1)
    expected |= iproute.IF_RA_OTHERCONF
    self.assertEqual(expected, GetInterfaceIpv6Flags(iface))

    self.SendRA(netid, m=0, o=1)
    expected &= ~iproute.IF_RA_MANAGED
    self.assertEqual(expected, GetInterfaceIpv6Flags(iface))


class PMTUTest(multinetwork_base.InboundMarkingTest):

  PAYLOAD_SIZE = 1400
  dstaddrs = set()

  def GetSocketMTU(self, version, s):
    if version == 6:
      ip6_mtuinfo = s.getsockopt(net_test.SOL_IPV6, csocket.IPV6_PATHMTU, 32)
      unused_sockaddr, mtu = struct.unpack("=28sI", ip6_mtuinfo)
      return mtu
    else:
      return s.getsockopt(net_test.SOL_IP, csocket.IP_MTU)

  def DisableFragmentationAndReportErrors(self, version, s):
    if version == 4:
      s.setsockopt(net_test.SOL_IP, csocket.IP_MTU_DISCOVER,
                   csocket.IP_PMTUDISC_DO)
      s.setsockopt(net_test.SOL_IP, net_test.IP_RECVERR, 1)
    else:
      s.setsockopt(net_test.SOL_IPV6, csocket.IPV6_DONTFRAG, 1)
      s.setsockopt(net_test.SOL_IPV6, net_test.IPV6_RECVERR, 1)

  def CheckPMTU(self, version, use_connect, modes):

    def SendBigPacket(version, s, dstaddr, netid, payload):
      if use_connect:
        s.send(payload)
      else:
        self.SendOnNetid(version, s, dstaddr, 1234, netid, payload, [])

    for netid in self.tuns:
      for mode in modes:
        s = self.BuildSocket(version, net_test.UDPSocket, netid, mode)
        self.DisableFragmentationAndReportErrors(version, s)

        srcaddr = self.MyAddress(version, netid)
        dst_prefix, intermediate = {
            4: ("172.19.", "172.16.9.12"),
            6: ("2001:db8::", "2001:db8::1")
        }[version]

        # Run this test often enough (e.g., in presubmits), and eventually
        # we'll be unlucky enough to pick the same address twice, in which
        # case the test will fail because the kernel will already have seen
        # the lower MTU. Don't do this.
        dstaddr = self.GetRandomDestination(dst_prefix)
        while dstaddr in self.dstaddrs:
          dstaddr = self.GetRandomDestination(dst_prefix)
        self.dstaddrs.add(dstaddr)

        if use_connect:
          s.connect((dstaddr, 1234))

        payload = self.PAYLOAD_SIZE * b"a"

        # Send a packet and receive a packet too big.
        SendBigPacket(version, s, dstaddr, netid, payload)
        received = self.ReadAllPacketsOn(netid)
        self.assertEqual(1, len(received),
                          "unexpected packets: %s" % received[1:])
        _, toobig = packets.ICMPPacketTooBig(version, intermediate, srcaddr,
                                             received[0])
        self.ReceivePacketOn(netid, toobig)

        # Check that another send on the same socket returns EMSGSIZE.
        self.assertRaisesErrno(
            errno.EMSGSIZE,
            SendBigPacket, version, s, dstaddr, netid, payload)

        # If this is a connected socket, make sure the socket MTU was set.
        # Note that in IPv4 this only started working in Linux 3.6!
        if use_connect:
          self.assertEqual(packets.PTB_MTU, self.GetSocketMTU(version, s))

        s.close()

        # Check that other sockets pick up the PMTU we have been told about by
        # connecting another socket to the same destination and getting its MTU.
        # This new socket can use any method to select its outgoing interface;
        # here we use a mark for simplicity.
        s2 = self.BuildSocket(version, net_test.UDPSocket, netid, "mark")
        s2.connect((dstaddr, 1234))
        self.assertEqual(packets.PTB_MTU, self.GetSocketMTU(version, s2))

        # Also check the MTU reported by ip route get, this time using the oif.
        routes = self.iproute.GetRoutes(dstaddr, self.ifindices[netid], 0, None)
        self.assertTrue(routes)
        route = routes[0]
        rtmsg, attributes = route
        self.assertEqual(iproute.RTN_UNICAST, rtmsg.type)
        metrics = attributes["RTA_METRICS"]
        self.assertEqual(packets.PTB_MTU, metrics["RTAX_MTU"])

        s2.close()

  def testIPv4BasicPMTU(self):
    """Tests IPv4 path MTU discovery.

    Relevant kernel commits:
      upstream net-next:
        6a66271 ipv4, fib: pass LOOPBACK_IFINDEX instead of 0 to flowi4_iif

      android-3.10:
        4bc64dd ipv4, fib: pass LOOPBACK_IFINDEX instead of 0 to flowi4_iif
    """

    self.CheckPMTU(4, True, ["mark", "oif"])
    self.CheckPMTU(4, False, ["mark", "oif"])

  def testIPv6BasicPMTU(self):
    self.CheckPMTU(6, True, ["mark", "oif"])
    self.CheckPMTU(6, False, ["mark", "oif"])

  def testIPv4UIDPMTU(self):
    self.CheckPMTU(4, True, ["uid"])
    self.CheckPMTU(4, False, ["uid"])

  def testIPv6UIDPMTU(self):
    self.CheckPMTU(6, True, ["uid"])
    self.CheckPMTU(6, False, ["uid"])

  # Making Path MTU Discovery work on unmarked  sockets requires that mark
  # reflection be enabled. Otherwise the kernel has no way to know what routing
  # table the original packet used, and thus it won't be able to clone the
  # correct route.

  def testIPv4UnmarkedSocketPMTU(self):
    self.SetMarkReflectSysctls(1)
    try:
      self.CheckPMTU(4, False, [None])
    finally:
      self.SetMarkReflectSysctls(0)

  def testIPv6UnmarkedSocketPMTU(self):
    self.SetMarkReflectSysctls(1)
    try:
      self.CheckPMTU(6, False, [None])
    finally:
      self.SetMarkReflectSysctls(0)


class UidRoutingTest(multinetwork_base.MultiNetworkBaseTest):
  """Tests that per-UID routing works properly.

  Relevant kernel commits:
    upstream net-next:
      7d99569460 net: ipv4: Don't crash if passing a null sk to ip_do_redirect.
      d109e61bfe net: ipv4: Don't crash if passing a null sk to ip_rt_update_pmtu.
      35b80733b3 net: core: add missing check for uid_range in rule_exists.
      e2d118a1cb net: inet: Support UID-based routing in IP protocols.
      622ec2c9d5 net: core: add UID to flows, rules, and routes
      86741ec254 net: core: Add a UID field to struct sock.

    android-3.18:
      b004e79504 net: ipv4: Don't crash if passing a null sk to ip_rt_update_pmtu.
      04c0eace81 net: inet: Support UID-based routing in IP protocols.
      18c36d7b71 net: core: add UID to flows, rules, and routes
      80e3440721 net: core: Add a UID field to struct sock.
      fa8cc2c30c Revert "net: core: Support UID-based routing."
      b585141890 Revert "Handle 'sk' being NULL in UID-based routing."
      5115ab7514 Revert "net: core: fix UID-based routing build"
      f9f4281f79 Revert "ANDROID: net: fib: remove duplicate assignment"

    android-4.4:
      341965cf10 net: ipv4: Don't crash if passing a null sk to ip_rt_update_pmtu.
      344afd627c net: inet: Support UID-based routing in IP protocols.
      03441d56d8 net: core: add UID to flows, rules, and routes
      eb964bdba7 net: core: Add a UID field to struct sock.
      9789b697c6 Revert "net: core: Support UID-based routing."
  """

  def GetRulesAtPriority(self, version, priority):
    rules = self.iproute.DumpRules(version)
    out = [(rule, attributes) for rule, attributes in rules
           if attributes.get("FRA_PRIORITY", 0) == priority]
    return out

  def CheckInitialTablesHaveNoUIDs(self, version):
    rules = []
    for priority in [0, 32766, 32767]:
      rules.extend(self.GetRulesAtPriority(version, priority))
    for _, attributes in rules:
      self.assertNotIn("FRA_UID_RANGE", attributes)

  def testIPv4InitialTablesHaveNoUIDs(self):
    self.CheckInitialTablesHaveNoUIDs(4)

  def testIPv6InitialTablesHaveNoUIDs(self):
    self.CheckInitialTablesHaveNoUIDs(6)

  @staticmethod
  def _Random():
    return random.randint(1000000, 2000000)

  @staticmethod
  def _RandomUid(cls):
    return random.randint(cls.UID_RANGE_START, cls.UID_RANGE_END)

  def CheckGetAndSetRules(self, version):
    start, end = tuple(sorted([self._Random(), self._Random()]))
    table = self._Random()
    priority = self._Random()

    # Can't create a UID range to UID -1 because -1 is INVALID_UID...
    self.assertRaisesErrno(
        errno.EINVAL,
        self.iproute.UidRangeRule, version, True, 100, 0xffffffff, table,
        priority)

    # ... but -2 is valid.
    self.iproute.UidRangeRule(version, True, 100, 0xfffffffe, table, priority)
    self.iproute.UidRangeRule(version, False, 100, 0xfffffffe, table, priority)

    try:
      # Create a UID range rule.
      self.iproute.UidRangeRule(version, True, start, end, table, priority)

      # Check that deleting the wrong UID range doesn't work.
      self.assertRaisesErrno(
          errno.ENOENT,
          self.iproute.UidRangeRule, version, False, start, end + 1, table,
          priority)
      self.assertRaisesErrno(errno.ENOENT,
        self.iproute.UidRangeRule, version, False, start + 1, end, table,
        priority)

      # Check that the UID range appears in dumps.
      rules = self.GetRulesAtPriority(version, priority)
      self.assertTrue(rules)
      _, attributes = rules[-1]
      self.assertEqual(priority, attributes["FRA_PRIORITY"])
      uidrange = attributes["FRA_UID_RANGE"]
      self.assertEqual(start, uidrange.start)
      self.assertEqual(end, uidrange.end)
      self.assertEqual(table, attributes["FRA_TABLE"])
    finally:
      self.iproute.UidRangeRule(version, False, start, end, table, priority)
      self.assertRaisesErrno(
          errno.ENOENT,
          self.iproute.UidRangeRule, version, False, start, end, table,
          priority)

    fwmask = 0xfefefefe
    try:
      # Create a rule without a UID range.
      self.iproute.FwmarkRule(version, True, 300, fwmask, 301, priority + 1)

      # Check it doesn't have a UID range.
      rules = self.GetRulesAtPriority(version, priority + 1)
      self.assertTrue(rules)
      for _, attributes in rules:
        self.assertIn("FRA_TABLE", attributes)
        self.assertNotIn("FRA_UID_RANGE", attributes)
    finally:
      self.iproute.FwmarkRule(version, False, 300, fwmask, 301, priority + 1)

    # Test that EEXIST worksfor UID range rules too.
    ranges = [(100, 101), (100, 102), (99, 101), (1234, 5678)]
    dup = ranges[0]
    try:
      # Check that otherwise identical rules with different UID ranges can be
      # created without EEXIST.
      for start, end in ranges:
        self.iproute.UidRangeRule(version, True, start, end, table, priority)
      # ... but EEXIST is returned if the UID range is identical.
      self.assertRaisesErrno(
        errno.EEXIST,
        self.iproute.UidRangeRule, version, True, dup[0], dup[1], table,
        priority)
    finally:
      # Clean up.
      for start, end in ranges + [dup]:
        try:
          self.iproute.UidRangeRule(version, False, start, end, table,
                                    priority)
        except IOError:
          pass

  def testIPv4GetAndSetRules(self):
    self.CheckGetAndSetRules(4)

  def testIPv6GetAndSetRules(self):
    self.CheckGetAndSetRules(6)

  def testDeleteErrno(self):
    for version in [4, 6]:
      table = self._Random()
      priority = self._Random()
      self.assertRaisesErrno(
          errno.EINVAL,
          self.iproute.UidRangeRule, version, False, 100, 0xffffffff, table,
          priority)

  def ExpectNoRoute(self, addr, oif, mark, uid):
    # The lack of a route may be either an error, or an unreachable route.
    try:
      routes = self.iproute.GetRoutes(addr, oif, mark, uid)
      rtmsg, _ = routes[0]
      self.assertEqual(iproute.RTN_UNREACHABLE, rtmsg.type)
    except IOError as e:
      if int(e.errno) != int(errno.ENETUNREACH):
        raise e

  def ExpectRoute(self, addr, oif, mark, uid):
    routes = self.iproute.GetRoutes(addr, oif, mark, uid)
    rtmsg, _ = routes[0]
    self.assertEqual(iproute.RTN_UNICAST, rtmsg.type)

  def CheckGetRoute(self, version, addr):
    self.ExpectNoRoute(addr, 0, 0, 0)
    for netid in self.NETIDS:
      uid = self.UidForNetid(netid)
      self.ExpectRoute(addr, 0, 0, uid)
    self.ExpectNoRoute(addr, 0, 0, 0)

  def testIPv4RouteGet(self):
    self.CheckGetRoute(4, net_test.IPV4_ADDR)

  def testIPv6RouteGet(self):
    self.CheckGetRoute(6, net_test.IPV6_ADDR)

  def testChangeFdAttributes(self):
    netid = random.choice(self.NETIDS)
    uid = self._RandomUid(self)
    table = self._TableForNetid(netid)
    remoteaddr = self.GetRemoteAddress(6)
    s = socket(AF_INET6, SOCK_DGRAM, 0)

    def CheckSendFails():
      self.assertRaisesErrno(errno.ENETUNREACH,
                             s.sendto, b"foo", (remoteaddr, 53))
    def CheckSendSucceeds():
      self.assertEqual(len(b"foo"), s.sendto(b"foo", (remoteaddr, 53)))

    CheckSendFails()
    self.iproute.UidRangeRule(6, True, uid, uid, table, self.PRIORITY_UID)
    try:
      CheckSendFails()
      os.fchown(s.fileno(), uid, -1)
      CheckSendSucceeds()
      os.fchown(s.fileno(), -1, -1)
      CheckSendSucceeds()
      os.fchown(s.fileno(), -1, 12345)
      CheckSendSucceeds()
      os.fchmod(s.fileno(), 0o777)
      CheckSendSucceeds()
      os.fchown(s.fileno(), 0, -1)
      CheckSendFails()
    finally:
      self.iproute.UidRangeRule(6, False, uid, uid, table, self.PRIORITY_UID)
      s.close()


class RulesTest(net_test.NetworkTest):

  RULE_PRIORITY = 99999
  FWMASK = 0xffffffff

  def setUp(self):
    self.iproute = iproute.IPRoute()
    for version in [4, 6]:
      self.iproute.DeleteRulesAtPriority(version, self.RULE_PRIORITY)

  def tearDown(self):
    for version in [4, 6]:
      self.iproute.DeleteRulesAtPriority(version, self.RULE_PRIORITY)

  def testRuleDeletionMatchesTable(self):
    for version in [4, 6]:
      # Add rules with mark 300 pointing at tables 301 and 302.
      # This checks for a kernel bug where deletion request for tables > 256
      # ignored the table.
      self.iproute.FwmarkRule(version, True, 300, self.FWMASK, 301,
                              priority=self.RULE_PRIORITY)
      self.iproute.FwmarkRule(version, True, 300, self.FWMASK, 302,
                              priority=self.RULE_PRIORITY)
      # Delete rule with mark 300 pointing at table 302.
      self.iproute.FwmarkRule(version, False, 300, self.FWMASK, 302,
                              priority=self.RULE_PRIORITY)
      # Check that the rule pointing at table 301 is still around.
      attributes = [a for _, a in self.iproute.DumpRules(version)
                    if a.get("FRA_PRIORITY", 0) == self.RULE_PRIORITY]
      self.assertEqual(1, len(attributes))
      self.assertEqual(301, attributes[0]["FRA_TABLE"])


if __name__ == "__main__":
  unittest.main()
