summaryrefslogtreecommitdiff
path: root/src/ipcpd/unicast/pff.c
blob: 192552b90228162c5d915ca2ef80cd55bb3e8e7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * Ouroboros - Copyright (C) 2016 - 2021
 *
 * PDU Forwarding Function
 *
 *    Dimitri Staessens <dimitri@ouroboros.rocks>
 *    Sander Vrijders   <sander@ouroboros.rocks>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., http://www.fsf.org/about/contact/.
 */

#define OUROBOROS_PREFIX "pff"

#include <ouroboros/errno.h>
#include <ouroboros/logs.h>

#include "pff.h"
#include "pff/ops.h"
#include "pff/alternate.h"
#include "pff/multipath.h"
#include "pff/simple.h"

struct pff {
        struct pff_ops * ops;
        struct pff_i *   pff_i;
};

struct pff * pff_create(enum pol_pff pol)
{
        struct pff * pff;

        pff = malloc(sizeof(*pff));
        if (pff == NULL)
                return NULL;

        switch (pol) {
        case PFF_ALTERNATE:
                log_dbg("Using alternate PFF policy.");
                pff->ops = &alternate_pff_ops;
                break;
        case PFF_SIMPLE:
                log_dbg("Using simple PFF policy.");
                pff->ops = &simple_pff_ops;
                break;
        case PFF_MULTIPATH:
                log_dbg("Using multipath PFF policy.");
                pff->ops = &multipath_pff_ops;
                break;
        default:
                goto err;
        }

        pff->pff_i = pff->ops->create();
        if (pff->pff_i == NULL)
                goto err;

        return pff;
 err:
        free(pff);
        return NULL;
}

void pff_destroy(struct pff * pff)
{
        pff->ops->destroy(pff->pff_i);

        free(pff);
}

void pff_lock(struct pff * pff)
{
        return pff->ops->lock(pff->pff_i);
}

void pff_unlock(struct pff * pff)
{
        return pff->ops->unlock(pff->pff_i);
}

int pff_add(struct pff * pff,
            uint64_t     addr,
            int *        fd,
            size_t       len)
{
        return pff->ops->add(pff->pff_i, addr, fd, len);
}

int pff_update(struct pff * pff,
               uint64_t     addr,
               int *        fd,
               size_t       len)
{
        return pff->ops->update(pff->pff_i, addr, fd, len);
}

int pff_del(struct pff * pff,
            uint64_t     addr)
{
        return pff->ops->del(pff->pff_i, addr);
}

void pff_flush(struct pff * pff)
{
        return pff->ops->flush(pff->pff_i);
}

int pff_nhop(struct pff * pff,
             uint64_t     addr)
{
        return pff->ops->nhop(pff->pff_i, addr);
}

int pff_flow_state_change(struct pff * pff,
                          int          fd,
                          bool         up)
{
        if (pff->ops->flow_state_change != NULL)
                return pff->ops->flow_state_change(pff->pff_i, fd, up);

        return 0;
}