]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - misc/ssfilter.y
Merge branch 'main' into next
[mirror_iproute2.git] / misc / ssfilter.y
index 4db3c95faa3ccfb7e1757abc87abcee01962e2f7..8e16b44638f6078e237fb3796d864708046b7072 100644 (file)
@@ -12,7 +12,14 @@ typedef struct ssfilter * ssfilter_t;
 
 static struct ssfilter * alloc_node(int type, void *pred)
 {
-       struct ssfilter *n = malloc(sizeof(*n));
+       struct ssfilter *n;
+
+       if (!ssfilter_is_supported(type)) {
+               fprintf(stderr, "It looks like such filter is not supported! Too old kernel?\n");
+               exit(-1);
+       }
+
+       n = malloc(sizeof(*n));
        if (n == NULL)
                abort();
        n->type = type;
@@ -36,28 +43,60 @@ static void yyerror(char *s)
 
 %}
 
-%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME MARKMASK FWMARK
+%token HOSTCOND DCOND SCOND DPORT SPORT LEQ GEQ NEQ AUTOBOUND DEVCOND DEVNAME MARKMASK FWMARK CGROUPCOND CGROUPPATH
 %left '|'
 %left '&'
 %nonassoc '!'
 
 %%
-applet: null expr
+applet: exprlist
         {
-                *yy_ret = $2;
-                $$ = $2;
+                *yy_ret = $1;
+                $$ = $1;
         }
         | null
         ;
+
 null:   /* NOTHING */ { $$ = NULL; }
         ;
-expr:  DCOND HOSTCOND
+
+exprlist: expr
+        | exprlist '|' expr
+        {
+                $$ = alloc_node(SSF_OR, $1);
+                $$->post = $3;
+        }
+        | exprlist '&' expr
+        {
+                $$ = alloc_node(SSF_AND, $1);
+                $$->post = $3;
+        }
+        | exprlist expr
+        {
+                $$ = alloc_node(SSF_AND, $1);
+                $$->post = $2;
+        }
+        ;
+
+eq:    '='
+       | /* nothing */
+       ;
+
+expr:  '(' exprlist ')'
+       {
+               $$ = $2;
+       }
+       | '!' expr
+       {
+               $$ = alloc_node(SSF_NOT, $2);
+       }
+       | DCOND eq HOSTCOND
         {
-               $$ = alloc_node(SSF_DCOND, $2);
+               $$ = alloc_node(SSF_DCOND, $3);
         }
-        | SCOND HOSTCOND
+        | SCOND eq HOSTCOND
         {
-               $$ = alloc_node(SSF_SCOND, $2);
+               $$ = alloc_node(SSF_SCOND, $3);
         }
         | DPORT GEQ HOSTCOND
         {
@@ -75,7 +114,7 @@ expr:        DCOND HOSTCOND
         {
                 $$ = alloc_node(SSF_NOT, alloc_node(SSF_D_GE, $3));
         }
-        | DPORT '=' HOSTCOND
+        | DPORT eq HOSTCOND
         {
                $$ = alloc_node(SSF_DCOND, $3);
         }
@@ -100,7 +139,7 @@ expr:       DCOND HOSTCOND
         {
                 $$ = alloc_node(SSF_NOT, alloc_node(SSF_S_GE, $3));
         }
-        | SPORT '=' HOSTCOND
+        | SPORT eq HOSTCOND
         {
                $$ = alloc_node(SSF_SCOND, $3);
         }
@@ -108,7 +147,7 @@ expr:       DCOND HOSTCOND
         {
                $$ = alloc_node(SSF_NOT, alloc_node(SSF_SCOND, $3));
         }
-        | DEVNAME '=' DEVCOND
+        | DEVNAME eq DEVCOND
         {
                $$ = alloc_node(SSF_DEVCOND, $3);
         }
@@ -116,7 +155,7 @@ expr:       DCOND HOSTCOND
         {
                $$ = alloc_node(SSF_NOT, alloc_node(SSF_DEVCOND, $3));
         }
-        | FWMARK '=' MARKMASK
+        | FWMARK eq MARKMASK
         {
                 $$ = alloc_node(SSF_MARKMASK, $3);
         }
@@ -124,33 +163,17 @@ expr:     DCOND HOSTCOND
         {
                 $$ = alloc_node(SSF_NOT, alloc_node(SSF_MARKMASK, $3));
         }
-        | AUTOBOUND
-        {
-                $$ = alloc_node(SSF_S_AUTO, NULL);
-        }
-        | expr '|' expr
-        {
-                $$ = alloc_node(SSF_OR, $1);
-               $$->post = $3;
-        }
-        | expr expr
-        {
-                $$ = alloc_node(SSF_AND, $1);
-               $$->post = $2;
-        }
-        | expr '&' expr
-
+        | CGROUPPATH eq CGROUPCOND
         {
-                $$ = alloc_node(SSF_AND, $1);
-               $$->post = $3;
+                $$ = alloc_node(SSF_CGROUPCOND, $3);
         }
-        | '!' expr
+        | CGROUPPATH NEQ CGROUPCOND
         {
-                $$ = alloc_node(SSF_NOT, $2);
+                $$ = alloc_node(SSF_NOT, alloc_node(SSF_CGROUPCOND, $3));
         }
-        | '(' expr ')'
+        | AUTOBOUND
         {
-                $$ = $2;
+                $$ = alloc_node(SSF_S_AUTO, NULL);
         }
 ;
 %%
@@ -268,6 +291,10 @@ int yylex(void)
                tok_type = FWMARK;
                return FWMARK;
        }
+       if (strcmp(curtok, "cgroup") == 0) {
+               tok_type = CGROUPPATH;
+               return CGROUPPATH;
+       }
        if (strcmp(curtok, ">=") == 0 ||
            strcmp(curtok, "ge") == 0 ||
            strcmp(curtok, "geq") == 0)
@@ -310,6 +337,14 @@ int yylex(void)
                }
                return MARKMASK;
        }
+       if (tok_type == CGROUPPATH) {
+               yylval = (void*)parse_cgroupcond(curtok);
+               if (yylval == NULL) {
+                       fprintf(stderr, "Cannot parse cgroup %s.\n", curtok);
+                       exit(1);
+               }
+               return CGROUPCOND;
+       }
        yylval = (void*)parse_hostcond(curtok, tok_type == SPORT || tok_type == DPORT);
        if (yylval == NULL) {
                fprintf(stderr, "Cannot parse dst/src address.\n");