13822cc986cc33751b82a22b91289ef088d94440cGregoire Baron/* 23822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * m_csum.c checksum updating action 33822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * 43822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * This program is free software; you can distribute it and/or 53822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * modify it under the terms of the GNU General Public License 63822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * as published by the Free Software Foundation; either version 73822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * 2 of the License, or (at your option) any later version. 83822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * 93822cc986cc33751b82a22b91289ef088d94440cGregoire Baron * Authors: Gregoire Baron <baronchon@n7mm.org> 103822cc986cc33751b82a22b91289ef088d94440cGregoire Baron */ 113822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 123822cc986cc33751b82a22b91289ef088d94440cGregoire Baron#include <stdio.h> 133822cc986cc33751b82a22b91289ef088d94440cGregoire Baron#include <stdlib.h> 143822cc986cc33751b82a22b91289ef088d94440cGregoire Baron#include <string.h> 153822cc986cc33751b82a22b91289ef088d94440cGregoire Baron#include <unistd.h> 163822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 173822cc986cc33751b82a22b91289ef088d94440cGregoire Baron#include <linux/tc_act/tc_csum.h> 183822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 193822cc986cc33751b82a22b91289ef088d94440cGregoire Baron#include "utils.h" 203822cc986cc33751b82a22b91289ef088d94440cGregoire Baron#include "tc_util.h" 213822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 223822cc986cc33751b82a22b91289ef088d94440cGregoire Baronstatic void 233822cc986cc33751b82a22b91289ef088d94440cGregoire Baronexplain(void) 243822cc986cc33751b82a22b91289ef088d94440cGregoire Baron{ 253822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(stderr, "Usage: ... csum <UPDATE>\n" 263822cc986cc33751b82a22b91289ef088d94440cGregoire Baron "Where: UPDATE := <TARGET> [<UPDATE>]\n" 273822cc986cc33751b82a22b91289ef088d94440cGregoire Baron " TARGET := { ip4h | icmp | igmp |" 283822cc986cc33751b82a22b91289ef088d94440cGregoire Baron " tcp | udp | udplite | <SWEETS> }\n" 293822cc986cc33751b82a22b91289ef088d94440cGregoire Baron " SWEETS := { and | or | \'+\' }\n"); 303822cc986cc33751b82a22b91289ef088d94440cGregoire Baron} 313822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 323822cc986cc33751b82a22b91289ef088d94440cGregoire Baronstatic void 333822cc986cc33751b82a22b91289ef088d94440cGregoire Baronusage(void) 343822cc986cc33751b82a22b91289ef088d94440cGregoire Baron{ 353822cc986cc33751b82a22b91289ef088d94440cGregoire Baron explain(); 363822cc986cc33751b82a22b91289ef088d94440cGregoire Baron exit(-1); 373822cc986cc33751b82a22b91289ef088d94440cGregoire Baron} 383822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 393822cc986cc33751b82a22b91289ef088d94440cGregoire Baronstatic int 403822cc986cc33751b82a22b91289ef088d94440cGregoire Baronparse_csum_args(int *argc_p, char ***argv_p, struct tc_csum *sel) 413822cc986cc33751b82a22b91289ef088d94440cGregoire Baron{ 423822cc986cc33751b82a22b91289ef088d94440cGregoire Baron int argc = *argc_p; 433822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char **argv = *argv_p; 443822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 453822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (argc <= 0) 463822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return -1; 473822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 483822cc986cc33751b82a22b91289ef088d94440cGregoire Baron while(argc > 0) { 493822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if ((matches(*argv, "iph") == 0) || 503822cc986cc33751b82a22b91289ef088d94440cGregoire Baron (matches(*argv, "ip4h") == 0) || 513822cc986cc33751b82a22b91289ef088d94440cGregoire Baron (matches(*argv, "ipv4h") == 0)) 523822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel->update_flags |= TCA_CSUM_UPDATE_FLAG_IPV4HDR; 533822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 543822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else if (matches(*argv, "icmp") == 0) 553822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel->update_flags |= TCA_CSUM_UPDATE_FLAG_ICMP; 563822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 573822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else if (matches(*argv, "igmp") == 0) 583822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel->update_flags |= TCA_CSUM_UPDATE_FLAG_IGMP; 593822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 603822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else if (matches(*argv, "tcp") == 0) 613822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel->update_flags |= TCA_CSUM_UPDATE_FLAG_TCP; 623822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 633822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else if (matches(*argv, "udp") == 0) 643822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel->update_flags |= TCA_CSUM_UPDATE_FLAG_UDP; 653822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 663822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else if (matches(*argv, "udplite") == 0) 673822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel->update_flags |= TCA_CSUM_UPDATE_FLAG_UDPLITE; 683822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 693822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else if ((matches(*argv, "and") == 0) || 703822cc986cc33751b82a22b91289ef088d94440cGregoire Baron (matches(*argv, "or") == 0) || 713822cc986cc33751b82a22b91289ef088d94440cGregoire Baron (matches(*argv, "+") == 0)) 723822cc986cc33751b82a22b91289ef088d94440cGregoire Baron ; /* just ignore: ... csum iph and tcp or udp */ 733822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else 743822cc986cc33751b82a22b91289ef088d94440cGregoire Baron break; 753822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argc--; 763822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argv++; 773822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 783822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 793822cc986cc33751b82a22b91289ef088d94440cGregoire Baron *argc_p = argc; 803822cc986cc33751b82a22b91289ef088d94440cGregoire Baron *argv_p = argv; 813822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 823822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return 0; 833822cc986cc33751b82a22b91289ef088d94440cGregoire Baron} 843822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 853822cc986cc33751b82a22b91289ef088d94440cGregoire Baronstatic int 863822cc986cc33751b82a22b91289ef088d94440cGregoire Baronparse_csum(struct action_util *a, int *argc_p, 873822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char ***argv_p, int tca_id, struct nlmsghdr *n) 883822cc986cc33751b82a22b91289ef088d94440cGregoire Baron{ 893822cc986cc33751b82a22b91289ef088d94440cGregoire Baron struct tc_csum sel; 903822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 913822cc986cc33751b82a22b91289ef088d94440cGregoire Baron int argc = *argc_p; 923822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char **argv = *argv_p; 933822cc986cc33751b82a22b91289ef088d94440cGregoire Baron int ok = 0; 943822cc986cc33751b82a22b91289ef088d94440cGregoire Baron struct rtattr *tail; 953822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 963822cc986cc33751b82a22b91289ef088d94440cGregoire Baron memset(&sel, 0, sizeof(sel)); 973822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 983822cc986cc33751b82a22b91289ef088d94440cGregoire Baron while (argc > 0) { 993822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (matches(*argv, "csum") == 0) { 1003822cc986cc33751b82a22b91289ef088d94440cGregoire Baron NEXT_ARG(); 1013822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (parse_csum_args(&argc, &argv, &sel)) { 1023822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(stderr, "Illegal csum construct (%s)\n", 1033822cc986cc33751b82a22b91289ef088d94440cGregoire Baron *argv); 1043822cc986cc33751b82a22b91289ef088d94440cGregoire Baron explain(); 1053822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return -1; 1063822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1073822cc986cc33751b82a22b91289ef088d94440cGregoire Baron ok++; 1083822cc986cc33751b82a22b91289ef088d94440cGregoire Baron continue; 1093822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } else if (matches(*argv, "help") == 0) { 1103822cc986cc33751b82a22b91289ef088d94440cGregoire Baron usage(); 1113822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1123822cc986cc33751b82a22b91289ef088d94440cGregoire Baron else { 1133822cc986cc33751b82a22b91289ef088d94440cGregoire Baron break; 1143822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1153822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1163822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1173822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (!ok) { 1183822cc986cc33751b82a22b91289ef088d94440cGregoire Baron explain(); 1193822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return -1; 1203822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1213822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1223822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (sel.update_flags == 0) { 1233822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(stderr, "Illegal csum construct, empty <UPDATE> list\n"); 1243822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return -1; 1253822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1263822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1273822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (argc) { 1283822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (matches(*argv, "reclassify") == 0) { 1293822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel.action = TC_ACT_RECLASSIFY; 1303822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argc--; 1313822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argv++; 1323822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } else if (matches(*argv, "pipe") == 0) { 1333822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel.action = TC_ACT_PIPE; 1343822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argc--; 1353822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argv++; 1363822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } else if (matches(*argv, "drop") == 0 || 1373822cc986cc33751b82a22b91289ef088d94440cGregoire Baron matches(*argv, "shot") == 0) { 1383822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel.action = TC_ACT_SHOT; 1393822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argc--; 1403822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argv++; 1413822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } else if (matches(*argv, "continue") == 0) { 1423822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel.action = TC_ACT_UNSPEC; 1433822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argc--; 1443822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argv++; 1453822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } else if (matches(*argv, "pass") == 0) { 1463822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel.action = TC_ACT_OK; 1473822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argc--; 1483822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argv++; 1493822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1503822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1513822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1523822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (argc) { 1533822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (matches(*argv, "index") == 0) { 1543822cc986cc33751b82a22b91289ef088d94440cGregoire Baron NEXT_ARG(); 1553822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (get_u32(&sel.index, *argv, 10)) { 1563822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(stderr, "Illegal \"index\" (%s) <csum>\n", 1573822cc986cc33751b82a22b91289ef088d94440cGregoire Baron *argv); 1583822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return -1; 1593822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1603822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argc--; 1613822cc986cc33751b82a22b91289ef088d94440cGregoire Baron argv++; 1623822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1633822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 1643822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1653822cc986cc33751b82a22b91289ef088d94440cGregoire Baron tail = NLMSG_TAIL(n); 1663822cc986cc33751b82a22b91289ef088d94440cGregoire Baron addattr_l(n, MAX_MSG, tca_id, NULL, 0); 1673822cc986cc33751b82a22b91289ef088d94440cGregoire Baron addattr_l(n, MAX_MSG, TCA_CSUM_PARMS, &sel, sizeof(sel)); 1683822cc986cc33751b82a22b91289ef088d94440cGregoire Baron tail->rta_len = (char *)NLMSG_TAIL(n) - (char *)tail; 1693822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1703822cc986cc33751b82a22b91289ef088d94440cGregoire Baron *argc_p = argc; 1713822cc986cc33751b82a22b91289ef088d94440cGregoire Baron *argv_p = argv; 1723822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1733822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return 0; 1743822cc986cc33751b82a22b91289ef088d94440cGregoire Baron} 1753822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1763822cc986cc33751b82a22b91289ef088d94440cGregoire Baronstatic int 1773822cc986cc33751b82a22b91289ef088d94440cGregoire Baronprint_csum(struct action_util *au, FILE * f, struct rtattr *arg) 1783822cc986cc33751b82a22b91289ef088d94440cGregoire Baron{ 1793822cc986cc33751b82a22b91289ef088d94440cGregoire Baron struct tc_csum *sel; 1803822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1813822cc986cc33751b82a22b91289ef088d94440cGregoire Baron struct rtattr *tb[TCA_CSUM_MAX + 1]; 1823822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1833822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char *uflag_1 = ""; 1843822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char *uflag_2 = ""; 1853822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char *uflag_3 = ""; 1863822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char *uflag_4 = ""; 1873822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char *uflag_5 = ""; 1883822cc986cc33751b82a22b91289ef088d94440cGregoire Baron char *uflag_6 = ""; 1893822cc986cc33751b82a22b91289ef088d94440cGregoire Baron SPRINT_BUF(action_buf); 1903822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1913822cc986cc33751b82a22b91289ef088d94440cGregoire Baron int uflag_count = 0; 1923822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1933822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (arg == NULL) 1943822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return -1; 1953822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1963822cc986cc33751b82a22b91289ef088d94440cGregoire Baron parse_rtattr_nested(tb, TCA_CSUM_MAX, arg); 1973822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 1983822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (tb[TCA_CSUM_PARMS] == NULL) { 1993822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(f, "[NULL csum parameters]"); 2003822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return -1; 2013822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 2023822cc986cc33751b82a22b91289ef088d94440cGregoire Baron sel = RTA_DATA(tb[TCA_CSUM_PARMS]); 2033822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 2043822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (sel->update_flags & TCA_CSUM_UPDATE_FLAG_IPV4HDR) { 2053822cc986cc33751b82a22b91289ef088d94440cGregoire Baron uflag_1 = "iph"; 2063822cc986cc33751b82a22b91289ef088d94440cGregoire Baron uflag_count++; 2073822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 2083822cc986cc33751b82a22b91289ef088d94440cGregoire Baron #define CSUM_UFLAG_BUFFER(flag_buffer, flag_value, flag_string) \ 2093822cc986cc33751b82a22b91289ef088d94440cGregoire Baron do { \ 2103822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (sel->update_flags & flag_value) { \ 2113822cc986cc33751b82a22b91289ef088d94440cGregoire Baron flag_buffer = uflag_count > 0 ? \ 2123822cc986cc33751b82a22b91289ef088d94440cGregoire Baron ", " flag_string : flag_string; \ 2133822cc986cc33751b82a22b91289ef088d94440cGregoire Baron uflag_count++; \ 2143822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } \ 2153822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } while(0) 2163822cc986cc33751b82a22b91289ef088d94440cGregoire Baron CSUM_UFLAG_BUFFER(uflag_2, TCA_CSUM_UPDATE_FLAG_ICMP, "icmp"); 2173822cc986cc33751b82a22b91289ef088d94440cGregoire Baron CSUM_UFLAG_BUFFER(uflag_3, TCA_CSUM_UPDATE_FLAG_IGMP, "igmp"); 21890d98edf39dc7da64fdf79408d5378e8d88acbe3Anton Danilov CSUM_UFLAG_BUFFER(uflag_4, TCA_CSUM_UPDATE_FLAG_TCP, "tcp"); 2193822cc986cc33751b82a22b91289ef088d94440cGregoire Baron CSUM_UFLAG_BUFFER(uflag_5, TCA_CSUM_UPDATE_FLAG_UDP, "udp"); 2203822cc986cc33751b82a22b91289ef088d94440cGregoire Baron CSUM_UFLAG_BUFFER(uflag_6, TCA_CSUM_UPDATE_FLAG_UDPLITE, "udplite"); 2213822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (!uflag_count) { 2223822cc986cc33751b82a22b91289ef088d94440cGregoire Baron uflag_1 = "?empty"; 2233822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 2243822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 2253822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(f, "csum (%s%s%s%s%s%s) action %s\n", 2263822cc986cc33751b82a22b91289ef088d94440cGregoire Baron uflag_1, uflag_2, uflag_3, 2273822cc986cc33751b82a22b91289ef088d94440cGregoire Baron uflag_4, uflag_5, uflag_6, 2283822cc986cc33751b82a22b91289ef088d94440cGregoire Baron action_n2a(sel->action, action_buf, sizeof(action_buf))); 2293822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(f, "\tindex %d ref %d bind %d", sel->index, sel->refcnt, sel->bindcnt); 2303822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 2313822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (show_stats) { 2323822cc986cc33751b82a22b91289ef088d94440cGregoire Baron if (tb[TCA_CSUM_TM]) { 2333822cc986cc33751b82a22b91289ef088d94440cGregoire Baron struct tcf_t *tm = RTA_DATA(tb[TCA_CSUM_TM]); 2343822cc986cc33751b82a22b91289ef088d94440cGregoire Baron print_tm(f,tm); 2353822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 2363822cc986cc33751b82a22b91289ef088d94440cGregoire Baron } 2373822cc986cc33751b82a22b91289ef088d94440cGregoire Baron fprintf(f, "\n"); 2383822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 2393822cc986cc33751b82a22b91289ef088d94440cGregoire Baron return 0; 2403822cc986cc33751b82a22b91289ef088d94440cGregoire Baron} 2413822cc986cc33751b82a22b91289ef088d94440cGregoire Baron 2423822cc986cc33751b82a22b91289ef088d94440cGregoire Baronstruct action_util csum_action_util = { 2433822cc986cc33751b82a22b91289ef088d94440cGregoire Baron .id = "csum", 2443822cc986cc33751b82a22b91289ef088d94440cGregoire Baron .parse_aopt = parse_csum, 2453822cc986cc33751b82a22b91289ef088d94440cGregoire Baron .print_aopt = print_csum, 2463822cc986cc33751b82a22b91289ef088d94440cGregoire Baron}; 247