How right to make second input chain in other table nftables? - firewall

There is my test nft ruleset , and all works except table inet test but table f2b-table is absolytly similar (except drop vs accept) and it works fine :
table inet f2b-table {
set addr-set-sshd {
type ipv4_addr
elements = { 0.0.0.0 }
}
chain input {
type filter hook input priority filter - 1; policy accept;
tcp dport { 222 } ip saddr #addr-set-sshd drop
}
}
table inet default {
set full_op_port {
type inet_service
elements = { 222 }
}
set allowed_ips {
type ipv4_addr
elements = { 0.0.0.0 }
}
chain INPUT {
type filter hook input priority filter; policy drop;
ct state invalid drop
ct state { established, related } accept
iif "lo" accept
tcp dport #full_op_port accept
ip saddr #allowed_ips accept
ip protocol icmp accept
counter packets 17 bytes 884
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
}
}
table ip test {
chain PREROUTING {
type nat hook prerouting priority filter; policy accept;
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
}
}
table inet test {
set op_port {
type inet_service
elements = { 8888 }
}
chain INPUT {
type filter hook input priority filter - 2; policy accept;
tcp dport #op_port accept
}
}
I see packages in tcpdump, i see packages when i makes count in table table inet test but packages don't be accepted. What do i make wrong?

I am adding another answer with examples here to clarify the unintended consequences of mixing policies with multiple base-chains of the same family, type and hook. Although priority can be made the same on these, it never should. Lower priority numbers mean a higher priority and will be run first. Applying drop policies incorrectly can cause unintended consequences for traffic you intend to accept.
As to the effect of mixing the hybrid family inet with ip and ip6, I won't even begin to pontificate except to say it's probably a bad idea.
WARNING: The examples horribly break ipv4 traffic and were performed on a VM - buyer beware !
An example of a bad drop policy:
table inet filter {
chain input1 {
type filter hook input priority filter + 1; policy drop;
tcp dport 80 log prefix "input1_" # SEEN
}
# input2 chain not evaluated as there is no traffic left after input1
chain input2 {
type filter hook input priority filter + 2; policy accept;
tcp dport 80 accept
tcp dport 80 log prefix "input2_"
}
}
An example of a ok drop policy:
table inet filter {
chain input1 {
type filter hook input priority filter + 1; policy accept;
tcp dport 80 log prefix "input1_" # SEEN
}
chain input2 {
type filter hook input priority filter + 2; policy drop;
tcp dport 80 accept
tcp dport 80 log prefix "input2_" # NOT SEEN due previous accept
}
}
An example of a bad accept policy:
table inet filter {
chain input1 {
type filter hook input priority filter + 1; policy accept;
tcp dport 80 accept
tcp dport 80 log prefix "input1_" # NOT SEEN due to previous accept
}
chain input2 {
type filter hook input priority filter + 2; policy drop;
tcp dport 80 log prefix "input2_" # SEEN - chain evaluates
# all traffic dropped here by policy including accepted input1 traffic
}
}
An example of an okay accept policy:
table inet filter {
chain input1 {
type filter hook input priority filter + 1; policy accept;
tcp dport 80 log prefix "input1_" # SEEN
}
chain input2 {
type filter hook input priority filter + 2; policy drop;
tcp dport 80 accept
tcp dport 80 log prefix "input2_" # NOT SEEN due to previous accept
}
}
As stated in the man page for nft, a drop by rule or policy drops immediately without further processing of lower priority base chains. accept does not. it short circuits remaining rules at the current priority and hands off to the next lower priority but here it is still subject to being dropped if explicitly dropped by rule or implicitly dropped by policy if there is no rule to accept.
Perhaps the easiest way to approach it is use a single base chain and jump/goto non-base chains, effectively the way iptables worked.

The answer comes from A.B where he stated:
just to clarify that a packet can be accepted (or not) multiple times in the same hook:
and posted from the nft man page
accept
Terminate ruleset evaluation and accept the packet. The packet can still be dropped
later by another hook, for instance accept in the forward hook still allows to drop the
packet later in the postrouting hook, or another forward base chain that has a higher
priority number and is evaluated afterwards in the processing pipeline.
Your default table base chain priority 0 will evaluate after your test table base chain priority -2 and because it has a drop policy and the packet is not matched there, it will be dropped.
The man page is confusing on this. Where it says for the allow verdict "terminate ruleset evaluation and accept the packet", it really only terminates the view of the ruleset at the given base chain priority. Other base chains of the same type, hook and family with lower priority due to the higher priority number will still run after and can override by rule or policy. This is unlike the drop verdict where all is stopped and the packet is summarily dropped. You can see this in action using logging:
nft flush ruleset
nft create table ip table1
nft add chain ip table1 input1 { type filter hook input priority filter\; policy drop\; }
nft add rule ip table1 input1 tcp dport != 8888 accept
nft add rule ip table1 input1 tcp dport 8888 log prefix \"TABLE1_INPUT1 DROPPING \" level info
nft create table ip table2
nft add chain ip table2 input2 { type filter hook input priority filter - 1\; policy accept\; }
nft add rule ip table2 input2 tcp dport != 8888 accept
nft add rule ip table2 input2 tcp dport 8888 log prefix \"TABLE2_INPUT2 BEFORE \" level info
nft add rule ip table2 input2 tcp dport 8888 accept
nft add rule ip table2 input2 tcp dport 8888 log prefix \"TABLE2_INPUT2 AFTER \" level info

Related

Accessing routing table from agent to get next hop

I've set up my routing algorithm from node itself. After this I want to send datagrams from physical layer in that route itself.
For example if my routes are 1 to 2 and 2 to 3 and I want to send a datagram from 1 to 3 I want my datagram to go through 2.
For this routing table for 1 will be as follows:
Routing table for 1
to: 3 nextHop: 2
to: 2 nextHop: 2
to: 1 nextHop: 1
So I want my process msg function to be as follows:
void processMessage(Message msg) {
if (msg instanceof DatagramNtf && msg.protocol == PING_PROTOCOL && msg.to != nodeInfo.addr)
def dG = new DatagramReq(to: routes.nextHop(msg.to), destination: msg.to)
send new DatagramReq(recipient: msg.sender, to: msg.from, protocol: Protocol.DATA)
}
also what routes.nextHop does is takes in the addr of the destination node and from the routing table gets the next hop.
I want to know to how to get the nextHop from routing table.
To send datagrams using route table entries, you need to use router agent, which inturn uses link and phy agents to send your datagram to the destination.Further routing of packets to the destination will be taken care by router agent itself.Hence I don't think you need to determine nextHop here for the to field in DatagramReq.
Your DatagramReq can be as-
router.send new DatagramReq(recipient: msg.sender, to: msg.from, protocol: Protocol.DATA)
Assuming router is the AgentID defined, and value of msg.from is your destination, and there is a valid route in the route table.
Further, nextHop or getNextHop() returns the address of neighbor node.

Unsure of how to set up and use dpdk-pktgen with RSS Enabled

I am in the process of buying a 25Gbe Card, and evaluating said card at the moment, and I can't seem to get it to receive a 25G Stream of 64 Byte UDP or TCP Packets traffic. Getting heavy packet drops, with dpdk-pktgen stating that It's using as many cores as I have set up. The most difficult thing to find out is why the packets are coming into the MAC but being dropped when they reach the Physical layer itself. Which leads me to believe that the dispersion of the reception of the packets is not being handled correctly. Leading me to believe that RSS is not taking place with the device, under dpdk. IRQ's are dispersed among the cores used in the system, which have been isolcpu'ed to keep the kernel from slating jobs on top of them, and all needed tuning seems to state that it has been done, and things should be moving along, but can't move past this hurdle.
Command run to initialize dpdk-pktgen:
RTE_SDK=../dpdk_Src/share/dpdk/ sudo -E ./app/build/pktgen -c 0x555555555 -n 8 w 03:00.1 -- -T -m '[2-28:29-33].0' -N -P
I read the documentation provided by DPDK RSS but have not been able to see any changes. I've altered the actual driver contained within dpdk's source "$RTE_SDK/drivers/net/mlx5/mlx5-rss.c" and added in the key that it suggests, I've also manipulated the pktgen-port-cfg.c file with the same instructions altering the below snippet of code
const struct rte_eth_conf default_port_conf = {
.rxmode = {
.split_hdr_size = 0,
.header_split = 0, /**< Header Split disabled. */
.hw_ip_checksum = 0, /**< IP checksum offload disabled. */
.hw_vlan_filter = 0, /**< VLAN filtering enabled. */
.hw_vlan_strip = 0, /**< VLAN strip enabled. */
.hw_vlan_extend = 0, /**< Extended VLAN disabled. */
.jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
.hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = NULL,
.rss_key_len = 0,
.rss_hf = ETH_RSS_IP,
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
}, };
Changing the rx_adv_conf to reflect the key that i want to use ie.
.rx_adv_conf = {
.rss_conf = {
.rss_key = "65da65da65da65da65da65da65da65da65da65da",
.rss_key_len = 40,
.rss_hf = ETH_RSS_IP,
},
},
The thing is the documenation seems to state that as long as the rss_hf parameter is set, then it will use RSS, internally defined if not explicitly stated. And should that be the case is there a way to validate a per ring reception rate within pktgen, or ethtool or any other tool?
ETH_RSS_IP means we hash flows using source and destination IP. So in order to leverage the RSS the packets you generate should have different source/destination IPs.

How to add extra options to CoAP request?

I know that CoAP defines some options which can be included in the sending request and each option has their own number. The structure of the CoAP uri request looks like:
coap-URI = "coap:" "//" host [ ":" port ] path-abempty [ "?" query ]
where inside they include some options like: Uri-Host, Uri-Port, Uri-Path, and Uri-Query, and each of them has their own number, ex: 3 for Uri-Host, 11 for Uri Path.... . And I would like to add some more extra options to this CoAP request, for example some options number 256, 257...How can I do that?
Thank you in advanced
Son
I've managed to pass the Option Number 256.
CoapClient client = new CoapClient(...);
Request request = new Request(CoAP.Code.GET, CoAP.Type.NON);
OptionSet optionSet = new OptionSet();
optionSet.addOption(new Option(256, "admin:admin"));
request.setOptions(optionSet);
client.advanced(request); // or async version
client.shutdown();
At resource:
#Override
public void handleGET(CoapExchange exchange) {
OptionSet optionSet = exchange.advanced().getRequest().getOptions();
List<Option> options = optionSet.asSortedList();
options.stream()
.filter(o -> o.getNumber() == 256)
.findFirst()
.ifPresent(o -> System.err.println(o.getNumber() + " " + o.getStringValue()));
}
Output:
256 admin:admin
However, Option Number 256 may not be a proper choice in general:
RFC 7252 The Constrained Application Protocol (CoAP). 12.2. CoAP Option Numbers Registry
The IANA policy for future additions to this sub-registry is split
into three tiers as follows. The range of 0..255 is reserved for
options defined by the IETF (IETF Review or IESG Approval). The
range of 256..2047 is reserved for commonly used options with public
specifications (Specification Required). The range of 2048..64999 is
for all other options including private or vendor-specific ones,
which undergo a Designated Expert review to help ensure that the
option semantics are defined correctly. The option numbers between
65000 and 65535 inclusive are reserved for experiments. They are not
meant for vendor-specific use of any kind and MUST NOT be used in
operational deployments.

how to order freeradius attributes

I am configuring Freeradius. Input message is Access-Request with Proxy-State = 3134
Freeradius succesfully performs authentication but he places Proxy-State at the bottom of Access-Accept. How can I canfigure that Freeradius places Framed-IP-Address at the bottom of the message?
It tried to configure "users" as:
381603854966 Auth-Type := Accept, User-Password == "123456"
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Netmask = 255.255.255.0,
User-Name = 381603854966,
Framed-IP-Address = 10.10.40.22,
but without success - freeradius still puts Proxy-State and the bottom of Access-Accept. I also tried to configure policy.txt file like:
if (User-Name == "381603854966") {
reply .= {
Framed-IP-Address += "10.10.40.22"
}
}
I also tried this in policy.txt:
reply .= {
Framed-IP-Address = 10.10.40.22
}
didn't work. Anybody knows how can I place certain attribute at the bottom of the message?
Thank you, Mark
You can't. The server will add Proxy-State to the request before forwarding it upstream, and it'll always add it at the end of the list of attributes.
RFC 2865 section 5 states:
If multiple Attributes with the same Type are present, the order of
Attributes with the same Type MUST be preserved by any proxies. The
order of Attributes of different Types is not required to be
preserved. A RADIUS server or client MUST NOT have any dependencies
on the order of attributes of different types. A RADIUS server or
client MUST NOT require attributes of the same type to be contiguous.
If your application requires ordering of attributes of different types, it's not implementing the RADIUS protocol correctly and should be fixed.

getnameinfo returning numeric name with "%<interface>"

I'm using getnameinfo as follows:
ifaddrs *ifaddr = NULL, *ifa = NULL;
int rc, family, insize;
rc = getifaddrs(&ifaddr);
...
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
family = ifa->ifa_addr->sa_family
insize = (family == AF_INET) ?
(int)sizeof(struct sockaddr_in) :
(int)sizeof(struct sockaddr_in6);
char host[HOST_NAME_MAX];
rc = getnameinfo(ifa->ifa_addr, insize,
host, sizeof(host), NULL, 0, NI_NUMERICHOST);
}
...
When the function returns with an IPv6 address, it include the interface appended to the numeric IP address:
fe80::62a4:4cff:fe05:dc1b%eth0
What's the purpose of appending the interface to the numerical IP address?
Is there a flag available that controls the appending of the interface to the IP address?
fe80::* addresses are link-local in scope, which means the address is only valid for that particular network, the same address may reference a difference host on a different network. It is thus meaningless to specify a link-local address without specifying which network adapter. Also, DNS becomes rather meaningless outside of link-local scope such as provided by ZeroConf / multicast-DNS.
Unix hosts tend to specify the adapter by name, Windows hosts will specify the adapter by index. Note that Windows maintains separate interface indexes for IPv4 and IPv6.

Resources