vcap_tc.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /* Microchip VCAP TC
  3. *
  4. * Copyright (c) 2023 Microchip Technology Inc. and its subsidiaries.
  5. */
  6. #include <net/flow_offload.h>
  7. #include <net/ipv6.h>
  8. #include <net/tcp.h>
  9. #include "vcap_api_client.h"
  10. #include "vcap_tc.h"
  11. enum vcap_is2_arp_opcode {
  12. VCAP_IS2_ARP_REQUEST,
  13. VCAP_IS2_ARP_REPLY,
  14. VCAP_IS2_RARP_REQUEST,
  15. VCAP_IS2_RARP_REPLY,
  16. };
  17. enum vcap_arp_opcode {
  18. VCAP_ARP_OP_RESERVED,
  19. VCAP_ARP_OP_REQUEST,
  20. VCAP_ARP_OP_REPLY,
  21. };
  22. int vcap_tc_flower_handler_ethaddr_usage(struct vcap_tc_flower_parse_usage *st)
  23. {
  24. enum vcap_key_field smac_key = VCAP_KF_L2_SMAC;
  25. enum vcap_key_field dmac_key = VCAP_KF_L2_DMAC;
  26. struct flow_match_eth_addrs match;
  27. struct vcap_u48_key smac, dmac;
  28. int err = 0;
  29. flow_rule_match_eth_addrs(st->frule, &match);
  30. if (!is_zero_ether_addr(match.mask->src)) {
  31. vcap_netbytes_copy(smac.value, match.key->src, ETH_ALEN);
  32. vcap_netbytes_copy(smac.mask, match.mask->src, ETH_ALEN);
  33. err = vcap_rule_add_key_u48(st->vrule, smac_key, &smac);
  34. if (err)
  35. goto out;
  36. }
  37. if (!is_zero_ether_addr(match.mask->dst)) {
  38. vcap_netbytes_copy(dmac.value, match.key->dst, ETH_ALEN);
  39. vcap_netbytes_copy(dmac.mask, match.mask->dst, ETH_ALEN);
  40. err = vcap_rule_add_key_u48(st->vrule, dmac_key, &dmac);
  41. if (err)
  42. goto out;
  43. }
  44. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS);
  45. return err;
  46. out:
  47. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "eth_addr parse error");
  48. return err;
  49. }
  50. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_ethaddr_usage);
  51. int vcap_tc_flower_handler_ipv4_usage(struct vcap_tc_flower_parse_usage *st)
  52. {
  53. int err = 0;
  54. if (st->l3_proto == ETH_P_IP) {
  55. struct flow_match_ipv4_addrs mt;
  56. flow_rule_match_ipv4_addrs(st->frule, &mt);
  57. if (mt.mask->src) {
  58. err = vcap_rule_add_key_u32(st->vrule,
  59. VCAP_KF_L3_IP4_SIP,
  60. be32_to_cpu(mt.key->src),
  61. be32_to_cpu(mt.mask->src));
  62. if (err)
  63. goto out;
  64. }
  65. if (mt.mask->dst) {
  66. err = vcap_rule_add_key_u32(st->vrule,
  67. VCAP_KF_L3_IP4_DIP,
  68. be32_to_cpu(mt.key->dst),
  69. be32_to_cpu(mt.mask->dst));
  70. if (err)
  71. goto out;
  72. }
  73. }
  74. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS);
  75. return err;
  76. out:
  77. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ipv4_addr parse error");
  78. return err;
  79. }
  80. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_ipv4_usage);
  81. int vcap_tc_flower_handler_ipv6_usage(struct vcap_tc_flower_parse_usage *st)
  82. {
  83. int err = 0;
  84. if (st->l3_proto == ETH_P_IPV6) {
  85. struct flow_match_ipv6_addrs mt;
  86. struct vcap_u128_key sip;
  87. struct vcap_u128_key dip;
  88. flow_rule_match_ipv6_addrs(st->frule, &mt);
  89. /* Check if address masks are non-zero */
  90. if (!ipv6_addr_any(&mt.mask->src)) {
  91. vcap_netbytes_copy(sip.value, mt.key->src.s6_addr, 16);
  92. vcap_netbytes_copy(sip.mask, mt.mask->src.s6_addr, 16);
  93. err = vcap_rule_add_key_u128(st->vrule,
  94. VCAP_KF_L3_IP6_SIP, &sip);
  95. if (err)
  96. goto out;
  97. }
  98. if (!ipv6_addr_any(&mt.mask->dst)) {
  99. vcap_netbytes_copy(dip.value, mt.key->dst.s6_addr, 16);
  100. vcap_netbytes_copy(dip.mask, mt.mask->dst.s6_addr, 16);
  101. err = vcap_rule_add_key_u128(st->vrule,
  102. VCAP_KF_L3_IP6_DIP, &dip);
  103. if (err)
  104. goto out;
  105. }
  106. }
  107. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS);
  108. return err;
  109. out:
  110. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ipv6_addr parse error");
  111. return err;
  112. }
  113. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_ipv6_usage);
  114. int vcap_tc_flower_handler_portnum_usage(struct vcap_tc_flower_parse_usage *st)
  115. {
  116. struct flow_match_ports mt;
  117. u16 value, mask;
  118. int err = 0;
  119. flow_rule_match_ports(st->frule, &mt);
  120. if (mt.mask->src) {
  121. value = be16_to_cpu(mt.key->src);
  122. mask = be16_to_cpu(mt.mask->src);
  123. err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L4_SPORT, value,
  124. mask);
  125. if (err)
  126. goto out;
  127. }
  128. if (mt.mask->dst) {
  129. value = be16_to_cpu(mt.key->dst);
  130. mask = be16_to_cpu(mt.mask->dst);
  131. err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L4_DPORT, value,
  132. mask);
  133. if (err)
  134. goto out;
  135. }
  136. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_PORTS);
  137. return err;
  138. out:
  139. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "port parse error");
  140. return err;
  141. }
  142. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_portnum_usage);
  143. int vcap_tc_flower_handler_cvlan_usage(struct vcap_tc_flower_parse_usage *st)
  144. {
  145. enum vcap_key_field vid_key = VCAP_KF_8021Q_VID0;
  146. enum vcap_key_field pcp_key = VCAP_KF_8021Q_PCP0;
  147. struct flow_match_vlan mt;
  148. u16 tpid;
  149. int err;
  150. flow_rule_match_cvlan(st->frule, &mt);
  151. tpid = be16_to_cpu(mt.key->vlan_tpid);
  152. if (tpid == ETH_P_8021Q) {
  153. vid_key = VCAP_KF_8021Q_VID1;
  154. pcp_key = VCAP_KF_8021Q_PCP1;
  155. }
  156. if (mt.mask->vlan_id) {
  157. err = vcap_rule_add_key_u32(st->vrule, vid_key,
  158. mt.key->vlan_id,
  159. mt.mask->vlan_id);
  160. if (err)
  161. goto out;
  162. }
  163. if (mt.mask->vlan_priority) {
  164. err = vcap_rule_add_key_u32(st->vrule, pcp_key,
  165. mt.key->vlan_priority,
  166. mt.mask->vlan_priority);
  167. if (err)
  168. goto out;
  169. }
  170. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_CVLAN);
  171. return 0;
  172. out:
  173. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "cvlan parse error");
  174. return err;
  175. }
  176. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_cvlan_usage);
  177. int vcap_tc_flower_handler_vlan_usage(struct vcap_tc_flower_parse_usage *st,
  178. enum vcap_key_field vid_key,
  179. enum vcap_key_field pcp_key)
  180. {
  181. struct flow_match_vlan mt;
  182. int err;
  183. flow_rule_match_vlan(st->frule, &mt);
  184. if (mt.mask->vlan_id) {
  185. err = vcap_rule_add_key_u32(st->vrule, vid_key,
  186. mt.key->vlan_id,
  187. mt.mask->vlan_id);
  188. if (err)
  189. goto out;
  190. }
  191. if (mt.mask->vlan_priority) {
  192. err = vcap_rule_add_key_u32(st->vrule, pcp_key,
  193. mt.key->vlan_priority,
  194. mt.mask->vlan_priority);
  195. if (err)
  196. goto out;
  197. }
  198. if (mt.mask->vlan_tpid)
  199. st->tpid = be16_to_cpu(mt.key->vlan_tpid);
  200. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_VLAN);
  201. return 0;
  202. out:
  203. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "vlan parse error");
  204. return err;
  205. }
  206. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_vlan_usage);
  207. int vcap_tc_flower_handler_tcp_usage(struct vcap_tc_flower_parse_usage *st)
  208. {
  209. struct flow_match_tcp mt;
  210. u16 tcp_flags_mask;
  211. u16 tcp_flags_key;
  212. enum vcap_bit val;
  213. int err = 0;
  214. flow_rule_match_tcp(st->frule, &mt);
  215. tcp_flags_key = be16_to_cpu(mt.key->flags);
  216. tcp_flags_mask = be16_to_cpu(mt.mask->flags);
  217. if (tcp_flags_mask & TCPHDR_FIN) {
  218. val = VCAP_BIT_0;
  219. if (tcp_flags_key & TCPHDR_FIN)
  220. val = VCAP_BIT_1;
  221. err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_FIN, val);
  222. if (err)
  223. goto out;
  224. }
  225. if (tcp_flags_mask & TCPHDR_SYN) {
  226. val = VCAP_BIT_0;
  227. if (tcp_flags_key & TCPHDR_SYN)
  228. val = VCAP_BIT_1;
  229. err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_SYN, val);
  230. if (err)
  231. goto out;
  232. }
  233. if (tcp_flags_mask & TCPHDR_RST) {
  234. val = VCAP_BIT_0;
  235. if (tcp_flags_key & TCPHDR_RST)
  236. val = VCAP_BIT_1;
  237. err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_RST, val);
  238. if (err)
  239. goto out;
  240. }
  241. if (tcp_flags_mask & TCPHDR_PSH) {
  242. val = VCAP_BIT_0;
  243. if (tcp_flags_key & TCPHDR_PSH)
  244. val = VCAP_BIT_1;
  245. err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_PSH, val);
  246. if (err)
  247. goto out;
  248. }
  249. if (tcp_flags_mask & TCPHDR_ACK) {
  250. val = VCAP_BIT_0;
  251. if (tcp_flags_key & TCPHDR_ACK)
  252. val = VCAP_BIT_1;
  253. err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_ACK, val);
  254. if (err)
  255. goto out;
  256. }
  257. if (tcp_flags_mask & TCPHDR_URG) {
  258. val = VCAP_BIT_0;
  259. if (tcp_flags_key & TCPHDR_URG)
  260. val = VCAP_BIT_1;
  261. err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_L4_URG, val);
  262. if (err)
  263. goto out;
  264. }
  265. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_TCP);
  266. return err;
  267. out:
  268. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "tcp_flags parse error");
  269. return err;
  270. }
  271. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_tcp_usage);
  272. int vcap_tc_flower_handler_arp_usage(struct vcap_tc_flower_parse_usage *st)
  273. {
  274. struct flow_match_arp mt;
  275. u16 value, mask;
  276. u32 ipval, ipmsk;
  277. int err;
  278. flow_rule_match_arp(st->frule, &mt);
  279. if (mt.mask->op) {
  280. mask = 0x3;
  281. if (st->l3_proto == ETH_P_ARP) {
  282. value = mt.key->op == VCAP_ARP_OP_REQUEST ?
  283. VCAP_IS2_ARP_REQUEST :
  284. VCAP_IS2_ARP_REPLY;
  285. } else { /* RARP */
  286. value = mt.key->op == VCAP_ARP_OP_REQUEST ?
  287. VCAP_IS2_RARP_REQUEST :
  288. VCAP_IS2_RARP_REPLY;
  289. }
  290. err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ARP_OPCODE,
  291. value, mask);
  292. if (err)
  293. goto out;
  294. }
  295. /* The IS2 ARP keyset does not support ARP hardware addresses */
  296. if (!is_zero_ether_addr(mt.mask->sha) ||
  297. !is_zero_ether_addr(mt.mask->tha)) {
  298. err = -EINVAL;
  299. goto out;
  300. }
  301. if (mt.mask->sip) {
  302. ipval = be32_to_cpu((__force __be32)mt.key->sip);
  303. ipmsk = be32_to_cpu((__force __be32)mt.mask->sip);
  304. err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_SIP,
  305. ipval, ipmsk);
  306. if (err)
  307. goto out;
  308. }
  309. if (mt.mask->tip) {
  310. ipval = be32_to_cpu((__force __be32)mt.key->tip);
  311. ipmsk = be32_to_cpu((__force __be32)mt.mask->tip);
  312. err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_DIP,
  313. ipval, ipmsk);
  314. if (err)
  315. goto out;
  316. }
  317. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_ARP);
  318. return 0;
  319. out:
  320. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "arp parse error");
  321. return err;
  322. }
  323. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_arp_usage);
  324. int vcap_tc_flower_handler_ip_usage(struct vcap_tc_flower_parse_usage *st)
  325. {
  326. struct flow_match_ip mt;
  327. int err = 0;
  328. flow_rule_match_ip(st->frule, &mt);
  329. if (mt.mask->tos) {
  330. err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_TOS,
  331. mt.key->tos,
  332. mt.mask->tos);
  333. if (err)
  334. goto out;
  335. }
  336. st->used_keys |= BIT_ULL(FLOW_DISSECTOR_KEY_IP);
  337. return err;
  338. out:
  339. NL_SET_ERR_MSG_MOD(st->fco->common.extack, "ip_tos parse error");
  340. return err;
  341. }
  342. EXPORT_SYMBOL_GPL(vcap_tc_flower_handler_ip_usage);