def lisp_itr_kernel_filter(sources, dyn_eids): if (os.getenv("LISP_NO_IPTABLES") != None): lisp.lprint("User selected to suppress installing iptables rules") return #endif os.system("sudo iptables -t raw -N lisp") os.system("sudo iptables -t raw -A PREROUTING -j lisp") os.system("sudo ip6tables -t raw -N lisp") os.system("sudo ip6tables -t raw -A PREROUTING -j lisp") # # Have kernel process packets for local addresses when sourced from site # EIDs. We do not want the lisp-itr process to process such packets. # We want the kernel to deliver packets to and from local applications. # And we want the kernel to forward decapsulated packets out interfaces # leading the EIDs. # add = "sudo ip{}tables -t raw -A lisp -j ACCEPT -d {}" addr_set = ["127.0.0.1", "::1", "224.0.0.0/4 -p igmp", "ff00::/8", "fe80::/16"] addr_set += sources + lisp.lisp_get_all_addresses() for addr in addr_set: if (lisp.lisp_is_mac_string(addr)): continue six = "" if addr.find(":") == -1 else "6" os.system(add.format(six, addr)) #endfor # # When source and destination addresses are EIDs for this LISP site, # we want the kernel to do local routing. But as a PITR, we don't want # the kernel to route everything (EID-prefix 0.0.0.0/0) or we can't have # this process encapsulate for any source address to a destination EID. # if (lisp.lisp_pitr == False): add = "sudo ip{}tables -t raw -A lisp -j ACCEPT -s {} -d {}" check = "sudo ip{}tables -t raw -C lisp -j ACCEPT -s {} -d {}" for source in sources: if (lisp.lisp_is_mac_string(source)): continue if (source in dyn_eids): continue six = "" if source.find(":") == -1 else "6" for s in sources: if (lisp.lisp_is_mac_string(s)): continue if (s in dyn_eids): continue if (s.find(".") != -1 and source.find(".") == -1): continue if (s.find(":") != -1 and source.find(":") == -1): continue if (commands.getoutput(check.format(six, source, s)) == ""): continue #endif os.system(add.format(six, source, s)) #endfor #endfor #endif # # Now put in drop rules for each "lisp database-mapping" EID-prefix. # drop = "sudo ip{}tables -t raw -A lisp -j DROP -s {}" for source in sources: if (lisp.lisp_is_mac_string(source)): continue six = "" if source.find(":") == -1 else "6" os.system(drop.format(six, source)) #endif # # Print out rules we just configured. # rules = commands.getoutput("sudo iptables -t raw -S lisp").split("\n") rules += commands.getoutput("sudo ip6tables -t raw -S lisp").split("\n") lisp.lprint("Using kernel filters: {}".format(rules)) # # Check if we need to put in a iptables rule workaround for the virtio TCP # checksum corruption problem for KVM guest OSes. Check environmnt # variable LISP_VIRTIO_BUG. # # Note a debian host system that runs docker will need the following # command so ip6tables works inside of the docker container: # # sudo modprobe ip6table_filter # if (os.getenv("LISP_VIRTIO_BUG") != None): c = ("sudo iptables -A POSTROUTING -t mangle -p tcp -j " + \ "CHECKSUM --checksum-fill; ") c += ("sudo iptables -A POSTROUTING -t mangle -p udp -j " + \ "CHECKSUM --checksum-fill; ") c += ("sudo ip6tables -A POSTROUTING -t mangle -p tcp -j " + \ "CHECKSUM --checksum-fill; ") c += ("sudo ip6tables -A POSTROUTING -t mangle -p udp -j " + \ "CHECKSUM --checksum-fill") os.system(c) virtio = lisp.bold("virtio", False) lisp.lprint("{} bug workaround, configure '{}'".format(virtio, c)) #endif return
def lisp_itr_build_pcap_filter(sources, dyn_eids, l2_overlay, pitr): if (l2_overlay): pfilter = "ether[6:4] >= 0 and ether[10:2] >= 0" lisp.lprint("Using pcap filter: '{}'".format(pfilter)) return(pfilter) #endif ether_pfilter = "(not ether proto 0x806)" probe_pfilter = " or (udp src port 4342 and ip[28] == 0x28)" decent_pfilter = \ " or (ip[16] >= 224 and ip[16] < 240 and (ip[28] & 0xf0) == 0x30)" src_pfilter = "" dst_pfilter = "" for source in sources: insert_source = source if (lisp.lisp_is_mac_string(source)): insert_source = source.split("/")[0] insert_source = insert_source.replace("-", "") mac_str = [] for i in range(0, 12, 2): mac_str.append(insert_source[i:i+2]) insert_source = "ether host " + ":".join(mac_str) #endif src_pfilter += "{}".format(insert_source) if (source not in dyn_eids): dst_pfilter += "{}".format(insert_source) if (sources[-1] == source): break src_pfilter += " or " if (source not in dyn_eids): dst_pfilter += " or " #endfor if (dst_pfilter[-4::] == " or "): dst_pfilter = dst_pfilter[0:-4] # # If "lisp-nat = yes" is configured, then we are a PETR and we need # to accept packets for local EIDs (assigned to loopback interfaces). # So allow the first one to be accepted. # lisp_nat = commands.getoutput("egrep 'lisp-nat = yes' ./lisp.config") lisp_nat = (lisp_nat != "" and lisp_nat[0] == " ") loopback = lisp.lisp_get_loopback_address() if (lisp_nat) else None addr_pfilter = "" addresses = lisp.lisp_get_all_addresses() for addr in addresses: if (addr == loopback): continue addr_pfilter += "{}".format(addr) if (addresses[-1] == addr): break addr_pfilter += " or " #endif if (src_pfilter != ""): src_pfilter = " and (src net {})".format(src_pfilter) #endif if (dst_pfilter != ""): dst_pfilter = " and not (dst net {})".format(dst_pfilter) #endif if (addr_pfilter != ""): addr_pfilter = " and not (dst host {})".format(addr_pfilter) #endif # # A PITR wants to see packets from anywhere so it can encap to possible # LISP sites. But we want the kernel to route and consume for RLOCs for # this system. # if (pitr): dst_pfilter = "" addr_pfilter = addr_pfilter.replace("dst ", "") #endif # # Concatenate all the filters. # pfilter = ether_pfilter + src_pfilter + dst_pfilter + addr_pfilter pfilter += probe_pfilter pfilter += decent_pfilter lisp.lprint("Using pcap filter: '{}'".format(pfilter)) return(pfilter)