| # Copyright 2018 syzkaller project authors. All rights reserved. |
| # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| |
| include <linux/socket.h> |
| include <uapi/linux/netfilter/x_tables.h> |
| include <uapi/linux/netfilter_bridge.h> |
| include <uapi/linux/netfilter_bridge/ebtables.h> |
| include <uapi/linux/netfilter_bridge/ebt_802_3.h> |
| include <uapi/linux/netfilter_bridge/ebt_among.h> |
| include <uapi/linux/netfilter_bridge/ebt_arp.h> |
| include <uapi/linux/netfilter_bridge/ebt_ip.h> |
| include <uapi/linux/netfilter_bridge/ebt_ip6.h> |
| include <uapi/linux/netfilter_bridge/ebt_limit.h> |
| include <uapi/linux/netfilter_bridge/ebt_mark_m.h> |
| include <uapi/linux/netfilter_bridge/ebt_pkttype.h> |
| include <uapi/linux/netfilter_bridge/ebt_stp.h> |
| include <uapi/linux/netfilter_bridge/ebt_vlan.h> |
| include <uapi/linux/netfilter_bridge/ebt_arpreply.h> |
| include <uapi/linux/netfilter_bridge/ebt_nat.h> |
| include <uapi/linux/netfilter_bridge/ebt_log.h> |
| include <uapi/linux/netfilter_bridge/ebt_mark_t.h> |
| include <uapi/linux/netfilter_bridge/ebt_nflog.h> |
| include <uapi/linux/netfilter_bridge/ebt_redirect.h> |
| |
| setsockopt$EBT_SO_SET_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_SET_ENTRIES], val ptr[in, ebt_replace], len const[0]) |
| setsockopt$EBT_SO_SET_COUNTERS(fd sock_in, level const[SOL_IP], opt const[EBT_SO_SET_COUNTERS], val ptr[in, ebt_counters_info], len len[val]) |
| getsockopt$EBT_SO_GET_INFO(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INFO], val ptr[in, ebt_getinfo], len ptr[in, len[val, int32]]) |
| getsockopt$EBT_SO_GET_INIT_INFO(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INIT_INFO], val ptr[in, ebt_getinfo], len ptr[in, len[val, int32]]) |
| getsockopt$EBT_SO_GET_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_ENTRIES], val ptr[in, ebt_get_entries], len ptr[in, len[val, int32]]) |
| getsockopt$EBT_SO_GET_INIT_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INIT_ENTRIES], val ptr[in, ebt_get_entries], len ptr[in, len[val, int32]]) |
| |
| ebt_replace [ |
| filter ebt_replace_t["filter", EBT_FILTER_VALID_HOOKS, ebt_filter_targets] |
| nat ebt_replace_t["nat", EBT_NAT_VALID_HOOKS, ebt_nat_targets] |
| broute ebt_replace_t["broute", EBT_BROUTE_VALID_HOOKS, ebt_broute_targets] |
| ] [varlen] |
| |
| define NF_BR_PRE_ROUTING_BIT 1 << NF_BR_PRE_ROUTING |
| define NF_BR_LOCAL_IN_BIT 1 << NF_BR_LOCAL_IN |
| define NF_BR_FORWARD_BIT 1 << NF_BR_FORWARD |
| define NF_BR_LOCAL_OUT_BIT 1 << NF_BR_LOCAL_OUT |
| define NF_BR_POST_ROUTING_BIT 1 << NF_BR_POST_ROUTING |
| define NF_BR_BROUTING_BIT 1 << NF_BR_BROUTING |
| |
| define EBT_FILTER_VALID_HOOKS NF_BR_LOCAL_IN_BIT | NF_BR_FORWARD_BIT | NF_BR_LOCAL_OUT_BIT |
| define EBT_NAT_VALID_HOOKS NF_BR_PRE_ROUTING_BIT | NF_BR_LOCAL_OUT_BIT | NF_BR_POST_ROUTING_BIT |
| define EBT_BROUTE_VALID_HOOKS NF_BR_BROUTING_BIT |
| |
| type ebt_replace_t[NAME, HOOKS, TARGETS] { |
| name string[NAME, XT_TABLE_MAXNAMELEN] |
| valid_hooks const[HOOKS, int32] |
| nentries const[0, int32] |
| entries_size bytesize[entries, int32] |
| hook_entry array[const[0, intptr], NF_BR_NUMHOOKS] |
| num_counters const[0, int32] |
| counters ptr[out, array[xt_counters, 1]] |
| entries ptr[in, array[ebt_entries[TARGETS], 3:4]] |
| } |
| |
| type ebt_entries[TARGETS] { |
| distinguisher const[0, int32] |
| name string["", EBT_CHAIN_MAXNAMELEN] |
| counter_offset const[0, int32] |
| policy flags[ebt_entries_policy, int32] |
| nentries len[entries, int32] |
| entries array[ebt_entry[TARGETS], 0:2] |
| } |
| |
| ebt_entries_policy = EBT_DROP, EBT_ACCEPT, EBT_RETURN |
| ebt_verdicts = EBT_DROP, EBT_ACCEPT, EBT_RETURN, EBT_CONTINUE |
| |
| type ebt_entry[TARGETS] { |
| watchers ebt_entry_watchers[TARGETS] |
| target TARGETS |
| } [packed] |
| |
| type ebt_entry_watchers[TARGETS] { |
| matches ebt_entry_matches |
| watchers array[TARGETS, 0:2] |
| } [packed] |
| |
| ebt_entry_matches { |
| bitmask flags[ebt_entry_bitmask, int32] |
| invflags flags[ebt_entry_invflags, int32] |
| ethproto flags[ether_types, int16be] |
| in devname |
| logical_in devname |
| out devname |
| logical_out devname |
| sourcemac mac_addr |
| sourcemsk mac_addr_mask |
| destmac mac_addr |
| destmsk mac_addr_mask |
| # TODO: this asks for an offset type (field offset). |
| watchers_offset bytesize[parent, int32] |
| target_offset bytesize[ebt_entry_watchers, int32] |
| next_offset bytesize[ebt_entry, int32] |
| matches array[ebt_matches, 0:2] |
| } |
| |
| ebt_entry_bitmask = EBT_NOPROTO_F, EBT_802_3_F, EBT_SOURCEMAC_F, EBT_DESTMAC_F |
| ebt_entry_invflags = EBT_IPROTO, EBT_IIN, EBT_IOUT, EBT_ISOURCE, EBT_IDEST, EBT_ILOGICALIN, EBT_ILOGICALOUT |
| |
| define EBT_NOPROTO_F EBT_ENTRY_OR_ENTRIES | EBT_NOPROTO |
| define EBT_802_3_F EBT_ENTRY_OR_ENTRIES | EBT_802_3 |
| define EBT_SOURCEMAC_F EBT_ENTRY_OR_ENTRIES | EBT_SOURCEMAC |
| define EBT_DESTMAC_F EBT_ENTRY_OR_ENTRIES | EBT_DESTMAC |
| |
| ebt_tables = "filter", "nat", "broute" |
| |
| ebt_counters_info { |
| name string[ebt_tables, XT_TABLE_MAXNAMELEN] |
| valid_hooks const[0, int32] |
| nentries const[0, int32] |
| entries_size const[0, int32] |
| hook_entry array[const[0, intptr], NF_BR_NUMHOOKS] |
| num_counters len[counters1, int32] |
| counters ptr[out, array[xt_counters]] |
| entries const[0, intptr] |
| counters1 array[xt_counters] |
| } |
| |
| ebt_getinfo { |
| name string[ebt_tables, XT_TABLE_MAXNAMELEN] |
| valid_hooks const[0, int32] |
| nentries const[0, int32] |
| entries_size const[0, int32] |
| hook_entry array[const[0, intptr], NF_BR_NUMHOOKS] |
| num_counters const[0, int32] |
| counters const[0, intptr] |
| entries const[0, intptr] |
| } |
| |
| ebt_get_entries { |
| name string[ebt_tables, XT_TABLE_MAXNAMELEN] |
| valid_hooks const[0, int32] |
| nentries int32[3:4] |
| entries_size bytesize[entries, int32] |
| hook_entry array[const[0, intptr], NF_BR_NUMHOOKS] |
| num_counters len[counters, int32] |
| counters ptr[out, array[xt_counters]] |
| entries ptr[out, array[int8]] |
| } |
| |
| # MATCHES: |
| |
| type ebt_entry_match[NAME, DATA] { |
| name string[NAME, EBT_FUNCTION_MAXNAMELEN] |
| match_size bytesize[data, int32] |
| data xt_padded[DATA] |
| } |
| |
| type xt_padded[TYPE] { |
| data TYPE |
| } [align_ptr] |
| |
| ebt_matches [ |
| m802_3 ebt_entry_match["802_3", ebt_802_3_info] |
| among ebt_entry_match["among", ebt_among_info] |
| arp ebt_entry_match["arp", ebt_arp_info] |
| ip ebt_entry_match["ip", ebt_ip_info] |
| ip6 ebt_entry_match["ip6", ebt_ip6_info] |
| limit ebt_entry_match["limit", ebt_limit_info] |
| mark_m ebt_entry_match["mark_m", ebt_mark_m_info] |
| pkttype ebt_entry_match["pkttype", ebt_pkttype_info] |
| stp ebt_entry_match["stp", ebt_stp_info] |
| vlan ebt_entry_match["vlan", ebt_vlan_info] |
| # AF_UNSPEC matches (only version 0 and not overriden by AF_BRIDGE). |
| cgroup0 ebt_entry_match["cgroup", xt_cgroup_info_v0] |
| helper ebt_entry_match["helper", xt_helper_info] |
| rateest ebt_entry_match["rateest", xt_rateest_match_info] |
| time ebt_entry_match["time", xt_time_info] |
| bpf0 ebt_entry_match["bpf", xt_bpf_info] |
| realm ebt_entry_match["realm", xt_realm_info] |
| connbytes ebt_entry_match["connbytes", xt_connbytes_info] |
| quota ebt_entry_match["quota", xt_quota_info] |
| ipvs ebt_entry_match["ipvs", xt_ipvs_mtinfo] |
| nfacct ebt_entry_match["nfacct", xt_nfacct_match_info] |
| mac ebt_entry_match["mac", xt_mac_info] |
| comment ebt_entry_match["comment", xt_comment_info] |
| statistic ebt_entry_match["statistic", xt_statistic_info] |
| physdev ebt_entry_match["physdev", xt_physdev_info] |
| connlabel ebt_entry_match["connlabel", xt_connlabel_mtinfo] |
| devgroup ebt_entry_match["devgroup", xt_devgroup_info] |
| cluster ebt_entry_match["cluster", xt_cluster_match_info] |
| owner ebt_entry_match["owner", xt_owner_match_info] |
| u32 ebt_entry_match["u32", xt_u32] |
| cpu ebt_entry_match["cpu", xt_cpu_info] |
| state ebt_entry_match["state", xt_state_info] |
| ] [varlen] |
| |
| ebt_802_3_info { |
| sap flags[sap_values, int8] |
| type int16be |
| bitmask flags[ebt_802_3_flags, int8] |
| invflags flags[ebt_802_3_flags, int8] |
| } |
| |
| ebt_802_3_flags = EBT_802_3_SAP, EBT_802_3_TYPE, EBT_802_3 |
| |
| ebt_among_info { |
| # TODO: these 2 fields are offsets of dst and src |
| # dst and src can also be not present in the struct, in which case ofs are 0 |
| wh_dst_ofs int32 |
| wh_src_ofs int32 |
| bitmask flags[ebt_among_flags, int32] |
| dst ebt_mac_wormhash |
| src ebt_mac_wormhash |
| } [packed] |
| |
| ebt_mac_wormhash { |
| table array[int32, 257] |
| poolsize len[pool, int32] |
| pool array[ebt_mac_wormhash_tuple] |
| } |
| |
| ebt_mac_wormhash_tuple { |
| cmp array[int32, 2] |
| ip ipv4_addr |
| } |
| |
| ebt_among_flags = EBT_AMONG_DST_NEG, EBT_AMONG_SRC_NEG |
| |
| ebt_arp_info { |
| htype flags[arp_htypes, int16be] |
| ptype flags[ether_types, int16be] |
| op flags[arp_ops, int16be] |
| saddr ipv4_addr |
| smsk ipv4_addr_mask |
| daddr ipv4_addr |
| dmsk ipv4_addr_mask |
| smaddr mac_addr |
| smmsk mac_addr_mask |
| dmaddr mac_addr |
| dmmsk mac_addr_mask |
| bitmask flags[ebt_arp_flags, int8] |
| invflags flags[ebt_arp_flags, int8] |
| } |
| |
| ebt_arp_flags = EBT_ARP_OPCODE, EBT_ARP_HTYPE, EBT_ARP_PTYPE, EBT_ARP_SRC_IP, EBT_ARP_DST_IP, EBT_ARP_SRC_MAC, EBT_ARP_DST_MAC, EBT_ARP_GRAT |
| |
| ebt_ip_info { |
| saddr ipv4_addr |
| daddr ipv4_addr |
| smsk ipv4_addr_mask |
| dmsk ipv4_addr_mask |
| tos int8 |
| protocol flags[ipv4_types, int8] |
| bitmask flags[ebt_ip_flags, int8] |
| invflags flags[ebt_ip_flags, int8] |
| sport_min sock_port |
| sport_max sock_port |
| dport_min sock_port |
| dport_max sock_port |
| } |
| |
| ebt_ip_flags = EBT_IP_SOURCE, EBT_IP_DEST, EBT_IP_TOS, EBT_IP_PROTO, EBT_IP_SPORT, EBT_IP_DPORT |
| |
| ebt_ip6_info { |
| saddr ipv6_addr |
| daddr ipv6_addr |
| smsk ipv6_addr_mask |
| dmsk ipv6_addr_mask |
| tclass int8 |
| protocol flags[ipv6_types, int8] |
| bitmask flags[ebt_ip6_flags, int8] |
| invflags flags[ebt_ip6_flags, int8] |
| sport_min sock_port |
| sport_max sock_port |
| dport_min sock_port |
| dport_max sock_port |
| } |
| |
| ebt_ip6_flags = EBT_IP6_SOURCE, EBT_IP6_DEST, EBT_IP6_TCLASS, EBT_IP6_PROTO, EBT_IP6_SPORT, EBT_IP6_DPORT, EBT_IP6_ICMP6 |
| |
| ebt_limit_info { |
| avg int32 |
| burst int32 |
| prev intptr |
| credit int32 |
| credit_cap int32 |
| cost int32 |
| } |
| |
| ebt_mark_m_info { |
| mark intptr |
| mask intptr |
| invert flags[ebt_mark_m_flags, int8] |
| bitmask flags[ebt_mark_m_flags, int8] |
| } |
| |
| ebt_mark_m_flags = EBT_MARK_AND, EBT_MARK_OR |
| |
| ebt_pkttype_info { |
| pkt_type int8[0:7] |
| invert bool8 |
| } |
| |
| ebt_stp_info { |
| type int8 |
| config ebt_stp_config_info |
| bitmask flags[ebt_stp_flags, int16] |
| invflags flags[ebt_stp_flags, int16] |
| } |
| |
| ebt_stp_config_info { |
| flags int8 |
| root_priol int16 |
| root_priou int16 |
| root_addr mac_addr |
| root_addrmsk mac_addr_mask |
| root_costl int32 |
| root_costu int32 |
| sender_priol int16 |
| sender_priou int16 |
| sender_addr mac_addr |
| sender_addrmsk mac_addr_mask |
| portl sock_port |
| portu sock_port |
| msg_agel int16 |
| msg_ageu int16 |
| max_agel int16 |
| max_ageu int16 |
| hello_timel int16 |
| hello_timeu int16 |
| forward_delayl int16 |
| forward_delayu int16 |
| } |
| |
| ebt_stp_flags = EBT_STP_TYPE, EBT_STP_FLAGS, EBT_STP_ROOTPRIO, EBT_STP_ROOTADDR, EBT_STP_ROOTCOST, EBT_STP_SENDERPRIO, EBT_STP_SENDERADDR, EBT_STP_PORT, EBT_STP_MSGAGE, EBT_STP_MAXAGE, EBT_STP_HELLOTIME, EBT_STP_FWDD |
| |
| ebt_vlan_info { |
| id int16[0:4] |
| prio int8[0:7] |
| encap flags[ether_types, int16be] |
| bitmask flags[ebt_vlan_flags, int8] |
| invflags flags[ebt_vlan_flags, int8] |
| } |
| |
| ebt_vlan_flags = EBT_VLAN_ID, EBT_VLAN_PRIO, EBT_VLAN_ENCAP |
| |
| # TARGETS: |
| |
| type ebt_entry_target[NAME, DATA] { |
| name string[NAME, EBT_FUNCTION_MAXNAMELEN] |
| target_size bytesize[data, int32] |
| data xt_padded[DATA] |
| } |
| |
| ebt_targets [ |
| dnat ebt_entry_target["dnat", ebt_nat_info] |
| log ebt_entry_target["log", ebt_log_info] |
| mark ebt_entry_target["mark", ebt_mark_t_info] |
| nflog ebt_entry_target["nflog", ebt_nflog_info] |
| redirect ebt_entry_target["redirect", ebt_redirect_info] |
| # AF_UNSPEC targets (only version 0). |
| STANDARD ebt_entry_target["", flags[nf_verdicts, int32]] |
| ERROR ebt_entry_target["ERROR", array[int8, XT_FUNCTION_MAXNAMELEN]] |
| LED ebt_entry_target["LED", xt_led_info] |
| RATEEST ebt_entry_target["RATEEST", xt_rateest_target_info] |
| NFQUEUE0 ebt_entry_target["NFQUEUE", xt_NFQ_info] |
| CLASSIFY ebt_entry_target["CLASSIFY", xt_classify_target_info] |
| IDLETIMER ebt_entry_target["IDLETIMER", idletimer_tg_info] |
| AUDIT ebt_entry_target["AUDIT", xt_audit_info] |
| CONNSECMARK ebt_entry_target["CONNSECMARK", xt_connsecmark_target_info] |
| SECMARK ebt_entry_target["SECMARK", xt_secmark_target_info] |
| NFLOG ebt_entry_target["NFLOG", xt_nflog_info] |
| ] [varlen] |
| |
| ebt_filter_targets [ |
| common ebt_targets |
| ] [varlen] |
| |
| ebt_nat_targets [ |
| common ebt_targets |
| arpreply ebt_entry_target["arpreply", ebt_arpreply_info] |
| snat ebt_entry_target["snat", ebt_nat_info] |
| ] [varlen] |
| |
| ebt_broute_targets [ |
| common ebt_targets |
| ] [varlen] |
| |
| ebt_arpreply_info { |
| mac mac_addr |
| # TODO: can also be jump target |
| target flags[ebt_verdicts, int32] |
| } |
| |
| ebt_nat_info { |
| mac mac_addr |
| # TODO: can also be jump target |
| target flags[ebt_nat_verdicts, int32] |
| } |
| |
| ebt_nat_verdicts = EBT_DROP, EBT_ACCEPT, EBT_RETURN, EBT_CONTINUE, NAT_ARP_BIT |
| |
| ebt_log_info { |
| loglevel int8 |
| prefix array[int8, EBT_LOG_PREFIX_SIZE] |
| bitmask flags[ebt_log_bitmask, int32] |
| } |
| |
| ebt_log_bitmask = EBT_LOG_IP, EBT_LOG_ARP, EBT_LOG_NFLOG, EBT_LOG_IP6 |
| |
| ebt_mark_t_info { |
| mark flags[ebt_mark_marks, intptr] |
| # TODO: can also be jump target |
| target flags[ebt_verdicts, int32] |
| } |
| |
| ebt_mark_marks = MARK_SET_VALUE, MARK_OR_VALUE, MARK_AND_VALUE, MARK_XOR_VALUE |
| |
| ebt_nflog_info { |
| len int32 |
| group int16 |
| threshold int16 |
| flags const[0, int16] |
| pad const[0, int16] |
| prefix array[int8, EBT_NFLOG_PREFIX_SIZE] |
| } |
| |
| ebt_redirect_info { |
| # TODO: can also be jump target |
| target flags[ebt_verdicts, int32] |
| } |